NASM - The Netwide Assembler
NASM Forum => Programming with NASM => Topic started by: jdubya on November 10, 2013, 07:52:19 PM
-
I'm working on a small project that gets a name and a number from user input. I want to add a number (eg. 5555) to the user entered number and then tell the user the answer. I having trouble and could use some help. Here's the code:
SECTION .data
askName: db "Enter your name: ",0
askNum: db "Enter an integer no more than four digits: ",0
formats: db "%s", 10, 0 ; string with line feed
formatsnlf db "%s",0 ; string w/o line feed
formatd: db "%d", 10, 0 ; integer with line feed
formatdnlf db "%d",0 ; integer w/o line feed
fResult: db "Thank you %s. After the addition to your number the sum is now: %d",10, 0
; arrays
number: times 4 db 0
; answer: times 4 db 0
SECTION .bss
name: resd 20
; number: resb 5
answer: resb 5
SECTION .text
extern printf
extern scanf
global main
main:
;set up stack frame
push EBP
mov EBP, ESP
pushad
;ask user name
push askName
call printf
add ESP, 8
; get name input
push name
push formats ; %s (string) and newline
call scanf
add ESP, 8
;ask user number
push askNum
call printf
add ESP, 4
; get usr number
push number
push formatd ; %d and line feed
call scanf
add ESP, 8
; add number to 5555 and print mess to usr
mov EAX, [number+5555]
mov [answer], EAX
push fResult ; final sentence
push formatsnlf
push formatd
call printf
add ESP, 12
; destroy stack frame
popad
mov ESP, EBP
pop EBP
ret
-
Well, I think you were okay up to here...
; add number to 5555 and print mess to usr
mov EAX, [number+5555]
mov [answer], EAX
push fResult ; final sentence
push formatsnlf
push formatd
call printf
add ESP, 12
"mov eax, [number + 5555]" is going to try to load a dword from memory at an address 5555 bytes beyond "number". You'll need to just "mov eax, [number]" and then "add eax, 5555" as a separate operation. Then... without pushing eax or the name, you push "fResult", a format string with tokens for both the name and the (new) number... and two more format strings. I'm pretty sure one format string per printf is the limit. I think you want to:
push eax ; or "push dword [answer]"
push name
push fResult
call printf
add esp, 12
That's untested.
Best,
Frank
-
A couple points of feedback are:
1. You're using "pushad" to save all the general purpose registers, this also saves ebp, so you could skip pushing ebp at the start, and just pushad/popad to get it back. On the other hand, this is a stand alone program, its not a procedure that'll be called by other programs or functions, so there's no reason I can see to save the registers at all. It looks like you're compiling with gcc or something, so all the prior parts of the program are doing is initialising stuff and figuring out where biits of the code will do; it's like the janitor, turning on the lights and getting out the tables and chairs for the big show, or a butler setting the table. It's a servant for the main program, it doesn't need the main program to do favours for it, keep values, it's just polite and deferential. All it wants from you is to make sure ebp is the same at the end of your program. When you ret, the butler cleans up the table, the janitor turns out the lights, it doesn't do anything functional besides tidy it all up, so no registers are really needed, except perhaps an error code (or 0 for no error) in eax if you want to be fancy. If someone's told you its 'good practice to save all registers' then they're into voodoo... its only worth it when you need to do it and thinking about whether you do or not is an important part of knowing why you're doing what you're doing.
2. It's not a big deal in a program like this which is for learning, but there are gaping security holes in the program as it stands, and it's a good thing to learn about them and spot them. You're taking input from a user and writing it to a 'buffer' with a fixed space. Most users may not have names over 20 characters in length, but I'm a nasty thinker, I'm not going to enter my name, I'm going to enter more than 20 characters and turn your program into my program, give it a whole new set of code... read up about it here: buffer overflows (http://en.wikipedia.org/wiki/Buffer_overflow)