I'm using the SASM IDE by Dmitry Manushin to write a program in FASM. My code is as follows:
format ELF
section '.data' writeable
msg db 'Hello, world of Flat ASM!', 0Dh, 0Ah, 00h ; terminate with null string
buffer rb 20
inp_buf_size rw 1
pkey db 'Press any key to exit ...', 0h
formatStr db "%s", 0
section '.text' executable
public _main
extrn _printf
extrn _getch
extrn _getche
_main:
mov ebp, esp; for correct debugging
push msg ; push message onto the stack
push formatStr ; push formatter onto the stack
call _printf ; call the printf method to print the message
add esp, 8 ; clean up
xor eax, eax
; press any key to exit
mov ebp, esp; for correct debugging
push pkey ; push message onto the stack
push formatStr ; push formatter onto the stack
call _printf ; call the printf method to print the message
add esp, 8
xor eax, eax
; get input here, using getch or getche (how? What must be pushed)
; mov ebp, esp; for correct debugging
; push buffer
; call _getch
; add esp, 8
; xor eax, eax
ret
Printing the "Hello, world ..." and "Press any key ..." code works as expected. What I'm stuck on is how I go about getting the program to wait for/read a single character into the buffer using _getch
. (What, if anything, should I push onto the stack before calling _getch
?) I've tried moving values into ah
and using interrupts, but this causes the program to crash.
$SOURCE$ $PROGRAM.OBJ$ -s $LSTOUTPUT$
$PROGRAM.OBJ$ $MACRO.OBJ$ -g -o $PROGRAM$ -m32
There are a few things going on here format ELF
tells FASM to create a Linux object file. Which feels a little odd because you are running Windows. But what makes it work is that SASM is using the MinGW version of the Linux gcc toolchain to create the executable. Which means you can write some Linux assembly but not everything can be Linux syntax.
Another issue is that getch
is not POSIX so could be causing problems, use getchar
instead.
And lastly windows does not exit programs by using return values in eax. The
xor eax, eax
ret
part will hang in Windows because of this. A safe way to do it is call _ExitProcess
passing it 0 on the stack.
It appears that SASM expects any input to be entered into the input box beforehand and because of that does not wait for the _getchar
. I left it in to show how it would work if SASM did not do this. Running similar code assembled directly using FASM works as expected.
Putting that all together this we get this:
format ELF
section '.data' writeable
msg db 'Hello, world of Flat ASM!', 0Dh, 0Ah, 00h
pkey db 'Press any key to exit ...', 0h
formatStr db "%s", 0
public _main
extrn _printf
extrn _getchar
extrn _ExitProcess
section '.text' executable
_main:
push msg
push formatStr
call _printf
push pkey
push formatStr
call _printf
call _getchar
push 0
call _ExitProcess
I removed the stack code for simplicity as this is only a hello world.