Help with this emu8086 assembly language problem please

In summary, the code successfully outputs the right decrement of the letter, but when I try to put space between the letters it becomes repetitive letters.
  • #1
chewi
6
0
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

1647765420194.png

when i try to put space it become like this
1647765555723.png

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
    1647765463753.png
    1.2 KB · Views: 122
Last edited:
Physics news on Phys.org
  • #2
Could you post your code, and say something about what it is intended to do?
 
  • Like
Likes chewi and Wrichik Basu
  • #3
sysprog said:
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
                        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
i want to put spaces on the output sequence, as well as make the output letters upper case
 
  • #4
In reverse order of what you asked:
chewi said:
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).
chewi said:
i want to put spaces on the output sequence,
After you print each character, then print a space character, ASCII 32 (0x20).
 
  • Like
Likes sysprog
  • #5
Mark44 said:
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?
 
  • #6
chewi said:
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.
 
  • #7
chewi said:
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.

sysprog said:
<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.
 
  • Like
Likes sysprog
  • #8
sysprog said:
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
                        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
                        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
 
 
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

 
print_space             proc near
                        mov dl, 20h
                        call print_char
                        ret
print_space             endpend                     drill_exer2
 
  • #9
Mark44 said:
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
 
  • #10
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
 
  • #11
chewi said:
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
 
  • #12
Mark44 said:
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 :wink:)
@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:
  • Like
Likes sysprog
  • #13
Tom.G said:
@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 :wink:)
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.
 
  • Like
Likes Tom.G
  • #14
Tom.G said:
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
 
  • Like
Likes sysprog
  • #15
willem2 said:
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.
 
  • Informative
Likes chewi
  • #16
sysprog said:
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
 
  • #17
Tom.G said:
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.
Tom.G said:
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."
 
  • Like
Likes Tom.G and chewi
  • #18
chewi said:
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.
 
  • Like
Likes chewi and pbuk
  • #19
sysprog said:
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:
  • Like
Likes sysprog
  • #20
pbuk said:
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:
  • #21
@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)​
 

FAQ: Help with this emu8086 assembly language problem please

How do I solve this emu8086 assembly language problem?

To solve this problem, you will need to carefully read the instructions and understand the purpose of the program. Then, you can start by breaking down the problem into smaller tasks and writing the necessary code to complete each task. It may also be helpful to refer to online resources or consult with others for guidance.

What is the purpose of this emu8086 assembly language problem?

The purpose of this problem is to test your understanding of assembly language and your ability to write efficient and effective code. It may also be used to assess your problem-solving skills and your ability to think critically.

How do I debug my emu8086 assembly language program?

To debug your program, you can use the step-by-step debugging feature in emu8086. This will allow you to execute your program line by line and track any errors or unexpected behavior. You can also use print statements or a debugger to identify and fix any issues in your code.

What are some common mistakes to avoid in emu8086 assembly language programming?

Some common mistakes to avoid include using incorrect syntax, not properly initializing variables, and not using the correct registers or addressing modes. It is also important to carefully track and manage memory usage to avoid errors such as overflow or underflow.

How can I improve my skills in emu8086 assembly language programming?

To improve your skills, you can practice regularly and challenge yourself with more complex problems. You can also read documentation and tutorials, attend workshops or classes, and participate in online forums or communities to learn from others and gain new insights and techniques.

Similar threads

Replies
1
Views
2K
Replies
9
Views
3K
Replies
4
Views
2K
Replies
4
Views
2K
Back
Top