Reputation: 63
I am very new to assembly programming and just writing small easy programs and doing lots of tutorials to try and teach myself. I spend most of my day using bash and python but assembly has a big advantage in my area of work plus I am fascinated by it to no end.
I am writing a small program to take user input of 'y' or 'n' compare it and output one of 2 messages. Its pretty straight forward however I am unable to figure out where my jump logic is failing and was wondering if anyone could point me in the right direction.
I am using NASM in windows 7 x64, this code compiles without an issue and I have traced the issue back to my jump instructions. Below is my code. My problem is that after entering y or n it does not seem to be calling yes_msg or no_msg properly and after an afternoon on google and on here I've been unable to figure it out. If anyone could help I'd be very grateful.
Thanks.
;compile with nasm.exe -f elf tutorial4.asm
;gcc -m32 tutorial4.o -o tutorial4.exe
global _main
extern _printf
extern _scanf
global _yes_msg
global _no_msg
section .data
msg db "Please say yes or no? [y/n] ", 0
msgy db "You said yes! ", 0
msgn db "You said no! ", 0
yes db 'y', 0
no db 'n', 0
fmt db "%s", 0
section .bss
inpt resb 200
section .text
_yes_msg:
push msgy
call _printf
add esp, 4
_no_msg:
push msgn
call _printf
add esp, 4
_main:
push ebp
mov ebp, esp
push msg
call _printf
add esp, 4
push inpt
push fmt
call _scanf
mov eax, inpt
mov edx, 'y'
cmp eax, edx
jne _no_msg
jmp _yes_msg
add esp, 8
mov esp, ebp
pop ebp
ret
Upvotes: 2
Views: 2052
Reputation: 4562
First, scanf returns number of processed entries (it will reside in eax). Check it, 0 means scanf rejected to parse (and you can't check the buffer because it could keep some garbage - according to NASM documentation, resb
provides uninitialized storage, which can be filled, for example, with runtime loader temporary values). You should rely on buffer contents only if scanf returned 1.
Second, your comparing deals with 4-byte values in eax and edx. Again, even if mov edx,'y'
fills it with 0x00000075, you can't be sure eax contains only the lowest significant byte. Call cmp al, dl
instead.
(BTW, your _yes_msg, _no_msg miss returning to main, and it will print "You said yes!" and then "You said no!" on 'y'. Is it intentional?)
Upvotes: 1
Reputation: 9899
Your instruction mov eax, inpt
moves the address of the buffer at inpt in the EAX register. You need the first byte at this location, so you have to write mov al, [inpt]
. Remember this is NASM!
Now you can compare the contents:
mov dl, 'y'
cmp al, dl
You placed the clean-up for your call to _scanf below an absolute jump and thus it will never be executed. Move it up to just under the call itself:
call _scanf
add esp, 8
mov al, [inpt]
As @Netch said you should probably change the codes at _yes_msg and _no_msg because now you get both messages in a row and additionally don't exit the program like it should.
Upvotes: 1