4
\$\begingroup\$

The following program takes a user-inputted integer and adds 155, shifts it to the right twice, and prints the output after the addition, then after the shift. It is written in fasm x86 assembly and uses the stdcall convention:

format PE Console
entry main
include 'macro/import32.inc'

; Read-Only data
section '.rdata' data readable
msg db 'Enter a number and we will do some math to it: ', 0
msg2 db 13,10, 'The final result is: %d', 0, 13, 10
p db 'pause>nul', 0
msg3 db 13, 10, '%d + 155 is %d', 0
msg4 db 'You entered: %d', 0
section '.data' data readable writeable
frmspec db '%d'
number dd 0


section '.code' code readable executable

main:
push ebp
mov ebp, esp
; no local vars needed
push msg
call [printf]
sub esp, 4 ; clean stack
push number
push frmspec
call [scanf]
sub esp, 8 ; clean stack
push [number]
push msg4
call [printf]
sub esp, 8 ; clean stack

mov eax, [number]
add eax, 155
push eax
push [number]
push msg3
call [printf]
pop ecx
pop eax
pop ecx

shr eax, 2
mov dword [number], eax
push [number]
push msg2
call [printf]
sub esp, 8
mov esp, ebp
pop ebp
push p
call [system]
sub esp, 4
push 0
call [exit]

;imports
section '.idata' import data readable
library msvcrt, 'msvcrt.dll'
import msvcrt, \
printf, 'printf', \
system, 'system', \
scanf, 'scanf', \
exit, 'exit'
\$\endgroup\$
6
\$\begingroup\$
push number
push frmspec
call [scanf]
sub esp, 8 ; clean stack

Cleaning up the stack is done by adding to esp. Because the stack on X86 grows downward, cleaning implies going upwards.
You make this mistake several times!


From your problem statement it's not very clear whether you want to

  • shift the number after the addition
  • shift the number as it was before the addition

Your code presently does the latter.

mov eax, [number]
add eax, 155
push eax
push [number]          <------ Original number
push msg3
call [printf]
pop ecx
pop eax                <------ Still original number
pop ecx
shr eax, 2             <------ Shifts the original number
mov dword [number], eax

frmspec db '%d'
number dd 0

Currently your program depends on the zero stored in number. In future you might want to re-use number several times and then the zero-terminator might not be there anymore.
I think it will be more robust if you wrote

frmspec db '%d', 0
number dd 0

msg2 db 13,10, 'The final result is: %d', 0, 13, 10

You've placed the zero before the carriage return/linefeed. Those won't be outputted as a consequence!


mov dword [number], eax

FASM does not require you to write this redundant size tag (dword). It serves no purpose.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.