Help with this emu8086 assembly language problem please

chewi
Summary:: my code has been successfully showing the right decrement of the letter. however, i tried to put space in between the letter output but its output became repititive letters.

this is the original output

when i try to put space it become like this

i want to put spaces on the output sequence, as well as make the output letters upper case

Code:
.model small
.code
org   0100h
call  clr_regs
jmp   drill_exer2

.data
first_char       db ?
stop_char        db ?
text1            db 10,    "Enter start letter (lowercase letter only): "  ,20h, "$" text2 db 13,10, "Enter last letter (lowercase letter only): " ,20h, "$"
text3            db 13,10, "Output sequence: "  ,20h,  "$" drill_exer2: lea dx, text1 call disp_string call read_char mov first_char, al lea dx, text2 call disp_string call read_char mov stop_char, al lea dx, text3 call disp_string mov dl, first_char next_char: call print_char call disp_del dec dl cmp dl, stop_char jne next_char call exit print_char proc near mov ah, 02h int 21h ret print_char endp disp_string proc near mov ah, 09h int 21h ret disp_string endp read_char proc near mov ah, 01h int 21h ret read_char endp clr_regs proc near xor ax, ax xor bx, bx xor cx, cx xor dx, dx ret clr_regs endp exit proc near mov ah, 4ch int 21h ret exit endp disp_del proc near mov cx, 000fh del: nop loop del ret disp_del endp end drill_exer2 Attachments • 1647765463753.png 1.2 KB · Views: 41 Last edited: Answers and Replies sysprog Could you post your code, and say something about what it is intended to do? chewi and Wrichik Basu chewi Could you post your code, and say something about what it is intended to do? original code: .model small .code org 0100h call clr_regs jmp drill_exer2 .data first_char db ? stop_char db ? text1 db 10, "Enter start letter (lowercase letter only): " ,20h, "$"
text2            db 13,10, "Enter last letter (lowercase letter only):  "  ,20h,  "$" text3 db 13,10, "Output sequence: " ,20h, "$"

drill_exer2:            lea     dx, text1
call    disp_string
mov     first_char, al

lea     dx, text2
call    disp_string
mov     stop_char, al

lea     dx, text3
call    disp_string

mov     dl, first_char

next_char:       call    print_char

call    disp_del

dec     dl
cmp     dl, stop_char
jne     next_char
call    exit

print_char              proc    near
mov     ah, 02h
int     21h
ret
print_char              endp

disp_string             proc    near
mov     ah, 09h
int     21h
ret
disp_string             endp

mov     ah, 01h
int     21h
ret

clr_regs                proc    near
xor     ax, ax
xor     bx, bx
xor     cx, cx
xor     dx, dx
ret
clr_regs                endp

exit                    proc    near
mov     ah, 4ch
int     21h
ret
exit                    endp

disp_del                proc    near
mov     cx, 000fh
del:        nop
loop    del
ret
disp_del                endp

end                     drill_exer2

i want to put spaces on the output sequence, as well as make the output letters upper case

Mentor
In reverse order of what you asked:
as well as make the output letters upper case
Subtract 32 (0x20) from each lowercase letter to get its uppercase equivalent. (Assuming you're working with ordinary ASCII letters.)
The ASCII code for 'a' is 97 (0x61); the ASCII code for 'A' is 65 (0x41).
i want to put spaces on the output sequence,
After you print each character, then print a space character, ASCII 32 (0x20).

sysprog
chewi
In reverse order of what you asked:

Subtract 32 (0x20) from each lowercase letter to get its uppercase equivalent. (Assuming you're working with ordinary ASCII letters.)
The ASCII code for 'a' is 97 (0x61); the ASCII code for 'A' is 65 (0x41).

After you print each character, then print a space character, ASCII 32 (0x20).
i tried to put print space character but the output becomes the 2nd picture attached. what could seem to be the problem?

sysprog
i tried to put print space character but the output becomes the 2nd picture attached. what could seem to be the problem?
Please show the modified code, too, so that we can see exactly how you "tried to put print space character" and got the result that your second picture shows.

Mentor
i tried to put print space character but the output becomes the 2nd picture attached. what could seem to be the problem?
So is the idea that if the first character entered is 'z' and the last character is 'a', the output should look like this?
Z Y X <etc.> D C B A

It looks like you are getting the space inserted but something else is wrong. One thing I noticed is that your disp_del routine is bogus -- all it does is iterate 15 times, doing nothing else. Since it's not doing anything useful, it should be removed.
Code:
disp_del                proc    near
mov     cx, 000fh
del:        nop
loop    del
ret
disp_del                endp

My advice for you is to take a step back, and make a better plan for your algorithm. Based on the first character entered and the next character entered, your program should figure out how many iterations of a loop it will need to use to print the sequence of characters.

<snip> and say something about what it is intended to do?
Yes, I agree with this. It isn't clear what problem you are trying to solve.

sysprog
chewi
Please show the modified code, too, so that we can see exactly how you "tried to put print space character" and got the result that your second picture shows.
modified code:
.model small
.code
org   0100h
call  clr_regs
jmp   drill_exer2

.data
first_char       db ?
stop_char        db ?
text1            db 10,    "Enter start letter (lowercase letter only): "  ,20h, "$" text2 db 13,10, "Enter last letter (lowercase letter only): " ,20h, "$"
text3            db 13,10, "Output sequence: "  ,20h,  "\$"

drill_exer2:            lea     dx, text1
call    disp_string
mov     first_char, al

lea     dx, text2
call    disp_string
mov     stop_char, al

lea     dx, text3
call    disp_string

mov     dl, first_char
mov     dh, dl
next_char:       call    print_char
call    print_space
call    disp_del
mov     dl, dh
dec     dl
cmp     dl, stop_char
jne     next_char
call    exit

print_char              proc    near
mov     ah, 02h
int     21h
ret
print_char              endp

disp_string             proc    near
mov     ah, 09h
int     21h
ret
disp_string             endp

mov     ah, 01h
int     21h
ret

clr_regs                proc    near
xor     ax, ax
xor     bx, bx
xor     cx, cx
xor     dx, dx
ret
clr_regs                endp

exit                    proc    near
mov     ah, 4ch
int     21h
ret
exit                    endp

disp_del                proc    near
mov     cx, 000fh
del:        nop
loop    del
ret
disp_del                endp

print_space             proc near
mov dl, 20h
call print_char
ret
print_space             endp

end                     drill_exer2

sysprog
One thing I noticed is that your disp_del routine is bogus -- all it does is iterate 15 times, doing nothing else. Since it's not doing anything useful, it should be removed.
Code:
disp_del                proc    near
mov     cx, 000fh
del:        nop
loop    del
ret
disp_del                endp
This looks to me like it's intended as a mini-template for doing something efficacious, as in:
Code:
disp_del                proc    near
mov     cx, 000fh     ; modify this as required for loop count
del:        nop                   ; insert code here
loop    del
ret
disp_del                endp

chewi
im sorry if i wasnt really clear with what i say. we just started lesson with this assembly language ang I am having hard time understanding the functions and how really the algorithms work. i hope you all understand

sysprog
im sorry if i wasnt really clear with what i say. we just started lesson with this assembly language ang I am having hard time understanding the functions and how really the algorithms work. i hope you all understand
It's ok, we were all beginners once.

Why call print_char from print_space? If you decide to, rather than in the main routine load a space and then call print_char, instead use a procedure that is specific to the space character, then why not issue the interrupt within that called procedure? ##-## as in:
snippet:
print_space             proc near
mov dl, 20h         ; character is 0x20, i.e. a space
mov ah, 02h         ; set request to 'display character'
int 21h             ; issue i/o interrupt
ret
print_space             endp

Gold Member
One thing I noticed is that your disp_del routine is bogus -- all it does is iterate 15 times, doing nothing else. Since it's not doing anything useful, it should be removed.
@Mark44, @sysprog, Most likely it is a delay loop for the display, probably to give the display time to actually display between characters. (although it should probably be called after every character, and would ideally be in the display driver and/or the operating system )

@chewi, Try drawing a picture (a flow chart) of the operations in "drill_exer2:" (lines 16 thru 37).
Flow chart symbols and their definitions are at https://www.gliffy.com/blog/guide-to-flowchart-symbols, for starters you only need the first 4 symbols for this. Be sure to include every line of code in the drawing, and add comments as needed that explain what the step is trying to accomplish. Then step thru (follow) the drawing to check what the computer is being told to do.

This approach is a great help in understanding programs because our brain tends to process pictures 'in parallel', that is we can get a better overall view of things and how they interact.

Hope this helps!

Cheers,
Tom

p.s. The problem seems to be one of those things all of us forget sometimes, even after decades of programming!

EDIT:
p.p.s. The Technical Reference for the operating system (MSDOS) shows that the contents of the CPU registers upon return from the INT 21H call are "NONE" (what was in them going in is not necessarily still there)!

Last edited:
sysprog
sysprog
@Mark44, @sysprog, Most likely it is a delay loop for the display, probably to give the display time to actually display between characters. (although it should probably be called after every character, and would ideally be in the display driver and/or the operating system )
I think that you're right about this ##-## I thought of the fact of the program being an exercise, rather than thinking of it running on an 8086 ##-## your explanation squares with the name of the subroutine, too.

Tom.G
willem2
EDIT:
p.p.s. The Technical Reference for the operating system (MSDOS) shows that the contents of the CPU registers upon return from the INT 21H call are "NONE" (what was in them going in is not necessarily still there)!
This is not true. int 21H saves all registers. The first program obviously did use dl after the int21h.
Note that print_space overwrites dl, and dl is saved in dh only once, and not before every call to print_space

sysprog
sysprog
This is not true. int 21H saves all registers. The first program obviously did use dl after the int21h.
Note that print_space overwrites dl, and dl is saved in dh only once, and not before every call to print_space
In the modified code, dh is copied to dl after the call to print_space and before dl is decremented ##-## dh should also be decremented at that point.

chewi
chewi
In the modified code, dh is copied to dl after the call to print_space and before dl is decremented ##-## dh should also be decremented at that point.
thank you so much this fixed the repititive outputs, i wonder where should i put th sub to make the output uppercase

Mentor
Most likely it is a delay loop for the display
Probably true but the name threw me off. I interpreted "disp_del" to have something to do with deletion rather than delay, as "del" is a much more common abbreviation for "delete." Two more letters in the label name and/or a comment would have been helpful.

In any case, I'm not sure how much a delay loop that executes only 15 times would slow down the display. I don't have an 8086 emulator, and I haven't written any code that uses the old DOS int 21h functionality since Windows went from 16 bits to 32 bits back in the 90s.
Try drawing a picture (a flow chart) of the operations in "drill_exer2:"
Flow charts are pretty much passe these days, with pseudocode being the preferred way to lay out the high-level operations of some code. However, I agree that a flow chart wouldn't hurt, in the absence of pseudocode.

The thread put me in mind of what the instructor in a CS class said one time -- "The sooner you sit down to the keyboard, the longer it takes to write your program."

Tom.G and chewi
sysprog
thank you so much this fixed the repititive outputs, i wonder where should i put th sub to make the output uppercase
Assuming that you are no longer calling print_char from print_space, you can do the uppercase conversion in print_char ##-## if you try to uppercase a space you'll get a null.

Subtracting 0x20 from the byte, as @Mark44 said, will convert a lowercase ASCII letter to uppercase ##-## the letter 'a' differs from the letter 'A' only in that the 6th bit from the right is 1 in lowercase and 0 in uppercase.

That means that instead of usingsub dl, 20h you could also instead useAND dl, 11011111b thus switching the 6th bit off while leaving the other bits unchanged.

chewi and pbuk
Homework Helper
Gold Member
That means that instead of usingsub dl, 20h you could also instead useAND dl, 11011111b thus switching the 6th bit off while leaving the other bits unchanged.
Yes this is the standard method for uppercasing: it has the advantage over subtraction that uppercase letters are unchanged i..e both A and a map to A (and similarly for lowercasing OR 20h is preferable to ADD 20h). Note however that the bit with the place value ## 20_{16} = 2^5 ## is usually called bit 5, not bit 6.

Last edited:
sysprog
sysprog
Yes this is the standard method for uppercasing: it has the advantage over subtraction that uppercase letters are unchanged i..e both A and a map to A (and similarly for lowercasing OR 20h is preferable to ADD 20h). Note however that the bit with the place value ## 20_{16) = 2^5 ## is usually called bit 5, not bit 6.
I didn't call it bit 6; I first called it the 6th bit from the right, and after that, the 6th bit ##-## if the convention is to designate the bit by its offset, rather than by its position within the byte (i.e. 'the bit at offset 5', rather than 'the bit at position 6'), then yes, the first bit is 'bit 0' (short for 'the bit at offset 0'), and the 6th bit is 'bit 5' ##-## I think that it's more perspicuous to call it the 6th bit.

Last edited:
sysprog
@pbuk, it seems that there's a different convention in some IBM usage ##-##

From https://www.ibm.com/docs/en/z-netview/6.2.0?topic=notations-using-bit-notation

Using Bit Notation​

Last Updated: 2021-04-15​
Another option is to specify a bit position. With a bit position, the rules of the comparison change, and the item you specify on the right side of the expression must be a bit string. Like byte positions, bit positions begin at one (1) rather than zero (0). (emphasis added)​