I'm trying to write a simple program that takes string from the keyboard, then prints it to the screen. So far I couldn't make it work.
Here's the code:
.section .rodata
output: .string "you entered %s\n"
input: .string "%s"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
subl $100, %esp
pushl $input
call scanf
movl %ebp, %esp
subl $100, %esp
pushl $output
call printf
xorl %eax, %eax
movl %ebp, %esp
popl %ebp
ret
When I execute it, the output is you entered (null)
for any given input.
when I set the offset of subl $100, %esp
command (the one before call print
) to subl $104, %esp
I get you entered %s
, and when the offset is set to 108 I get you entered *gibberish*
.
I feel like it's a game where I need to guess where scanf
saved the string on the stack (why isn't it where it should be?).
I am using IA32 instruction set.
Any help would be greatly appreciated.
Basically there are 3 problems in your program:
subl $100, %esp
pushl $input
# Error 1:
# As Frank Kotler already wrote at this point
# only $input is stored on the stack; however
# the address of the buffer must also be on
# the stack (see Frank Kotler's comment)
call scanf
movl %ebp, %esp
# Error 2:
# Now the buffer is below ESP.
# Because interrupts use the kernel stack they
# will not overwrite the memory below ESP.
# However signals will destroy the memory below
# ESP!!
#
# Instead of the lines:
# movl %ebp, %esp
# subl $100, %esp
#
# You should use something like this:
# add $8, %esp
# or:
# lea -100(%ebp), %esp
#
subl $100, %esp
# Error 3:
# As for "scanf" the second argument
# is missing on the stack
pushl $output
call printf