...

View Full Version : Assembly beginner help



mrmodest
09-23-2011, 04:41 AM
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!





; 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.

morongo47
09-23-2011, 08:11 PM
.
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.



; 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.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum