Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 2 of 2
  1. #1
    New to the CF scene
    Join Date
    Sep 2011
    Posts
    6
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Assembly beginner help

    Hey guys, I am trying to learn assembly and my teacher briefly went over push and pop today and told us we could practice by looking at this example code in emu8086 and try to reverse the string that the user enters in. I have figured out that I need to push bx until the string is reversed but I am not sure how to go about it. Can someone point me in the right direction or give me a hint? I have played around with the code a bit and managed to use xor and convert uppercase letters to lowercase, but this is the original code except for comments I have added during trying to figure it all out.

    Thanks!

    Code:
    
    ; this is a program in 8086 assembly language that
    ; accepts a character string from the keyboard and
    ; stores it in the string array. the program then converts 
    ; all the lower case characters of the string to upper case. 
    ; if the string is empty (null), it doesn't do anything.
    
    name "upper"
    
    org 100h
    
    
    jmp start
    
    
    ; first byte is buffer size,
    ; second byte will hold number
    ; of used bytes for string,
    ; all other bytes are for characters:
    string db 20, 22 dup('?')
    
    new_line db 0Dh,0Ah, '$'  ; new line code.
    
    start:
    
    ; int 21h / ah=0ah - input of a string to ds:dx, 
    ; fist byte is buffer size, second byte is number 
    ; of chars actually read. does not add '$' in the
    ; end of string. to print using int 21h / ah=09h
    ; you must set dollar sign at the end of it and 
    ; start printing from address ds:dx + 2.
    
    lea dx, string
    
    mov ah, 0ah
    int 21h ; interrupt looks in ah
    
    
    mov bx, dx    
    mov ah, 0
    mov al, ds:[bx+1]
    add bx, ax ; point to end of string.          
    
    
    
    mov byte ptr [bx+2], '$' ; endl.
    
    ; int 21h / ah=09h - output of a string at ds:dx.
    ; string must be terminated by '$' sign.
    lea dx, new_line
    mov ah, 09h
    int 21h
    
    
    lea bx, string
    
    mov ch, 0
    mov cl, [bx+1] ; get string size.
    
    jcxz null ; is string is empty?
    add bx, 2 ; skip control chars.
    
    upper_case:
    
    ; check if it's a lower case letter:
    cmp byte ptr [bx], 'a'
    jb ok
    cmp byte ptr [bx], 'z'
    ja ok
    
    and byte ptr [bx], 11011111b ; 
    
    ok:
    
    inc bx ; next char.
    loop upper_case
    
    
    ; int 21h / ah=09h - output of a string at ds:dx.
    ; string must be terminated by '$' sign.
    lea dx, string+2
    mov ah, 09h
    int 21h
     
    ; wait for any key press....
    mov ah, 0
    int 16h 
     
     
    null:
    ret  ; return to operating system.

  • #2
    New Coder
    Join Date
    Sep 2011
    Posts
    43
    Thanks
    6
    Thanked 6 Times in 6 Posts
    .
    It's been a long time since I've looked at any 8086 code (like maybe 1987), but it was fun trying to remember...

    Here's the deal, the stack (which is what holds all your 'pushes') is set by the system. If you're on a 32-bit system it's a DWORD, if you're emulating a 16-bit system it's a WORD, so that's what determines what size chunk of data you can 'push' (you can't just push any old byte).

    So, to use 'push' to save a byte to the stack, you have to save it to a register (which is WORD size on a 16-bit emu), you do that by saving it to either the high or low half of the register. In your case I used AH, then pushed AX. Later, I popped the stack back into AX and read the value in AH. I did both operations in a loop after getting the string size into CX which determined the number of iterations the loop would do.

    I hope that helps a little with the 'concept' part.

    Code:
    ; this is a program in 8086 assembly language that
    ; accepts a character string from the keyboard and
    ; stores it in the string array. the program then converts 
    ; all the lower case characters of the string to upper case. 
    ; if the string is empty (null), it doesn't do anything.
    
    name "upper"
    
    org 100h
    
    
    jmp start
    
    
    ; first byte is buffer size,
    ; second byte will hold number
    ; of used bytes for string,
    ; all other bytes are for characters:
    
    string    db 20, 22 dup('?')
    revstring db 20, 22 dup('?')  ;;new buf for rev-str
    size      dw  4                    ;;to save str size
    
    
    new_line db 0Dh,0Ah, '$'  ; new line code.
    
    start:
    
    ; int 21h / ah=0ah - input of a string to ds:dx, 
    ; fist byte is buffer size, second byte is number 
    ; of chars actually read. does not add '$' in the
    ; end of string. to print using int 21h / ah=09h
    ; you must set dollar sign at the end of it and 
    ; start printing from address ds:dx + 2.
    
    lea dx, string
    
    mov ah, 0ah
    int 21h ; interrupt looks in ah
    
    
    mov  bx, dx   
    mov  ah, 0
    mov  al, ds:[bx+1]
    add  bx, ax ; point to end of string.          
    
    
    mov byte ptr [bx+2], '$' ; endl.
    
    ; int 21h / ah=09h - output of a string at ds:dx.
    ; string must be terminated by '$' sign.
    lea dx, new_line
    mov ah, 09h
    int 21h
    
    
    lea bx, string
    
    mov   ch, 0
    mov   cl, [bx+1] ; get string size. 
    mov size, cx      ;;save size
    
    jcxz null ; is string is empty?
    add bx, 2 ; skip control chars.
    
    upper_case:
    ;;uncomment to show lower case reverse
    ;;mov  ah, byte ptr [bx]
    ;;push ax
    
    ; check if it's a lower case letter:
    cmp  byte ptr [bx], 'a'
    jb ok
    cmp  byte ptr [bx], 'z'
    ja ok
    
    and  byte ptr [bx], 11011111b ; 
    
    ok:
    ;;save char to the stack
    ;;comment out to show lower cas reverse
    mov  ah, byte ptr [bx]
    push ax
    
    inc bx ; next char.
    loop upper_case      
    
    
    ;;re-init string size
    mov cx, size
    
    ;;point to revstring buffer
    lea bx, revstring         
    
    ;;enter reverse loop
    reverse:
    pop ax
    mov byte ptr [bx], ah
    inc bx ; next char.
    loop reverse
    
    mov byte ptr [bx],'$' ;endl.
    
    ; int 21h / ah=09h - output of a string at ds:dx.
    ; string must be terminated by '$' sign.
    lea dx, revstring
    mov ah, 09h
    int 21h
     
    ; wait for any key press....
    mov ah, 0
    int 16h 
     
     
    null:
    ret  ; return to operating system.
    Last edited by morongo47; 09-23-2011 at 09:24 PM.


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •