Question

For a homework assignment, we have been asked to scan a number, increment it by one and print the answer. However, code tends to give a segmentation error.

.global main

mystring: .asciz "Assignment 3: inout\n"

string: .asciz "%d"

main:   pushl $mystring
        call printf
        jmp inout

end:    pushl $0
        call exit

This is basically what we're doing. Running a code like this without the jump works. The problem is in the inout method

inout:  subl $0, %esp             ;what is happening here
        leal -4(%ebp), %eax       ;what am i doing here
        pushl %ebp                ;why do i need to push the base pointer
        movl %esp, %ebp
        pushl %eax
        pushl $string
        call scanf
        incl %eax
        pushl %eax
        pushl $string
        call printf

Which doesn't seem to work. I also have no idea what the beginning (substract, address thing) means, see the commentary for further things. Thanks in advance!

Was it helpful?

Solution

Partial answer, but maybe this will help you track down the problem:

subl $0, %esp would grow the stack if the constant wasn't zero. The top of the stack is usually at the lowest memory address in x86, that is, stacks grow downwards.

leal -4(%ebp), %eax loads the absolute address %ebp - 4 into %eax. This is the pointer to the memory location where the scanfd integer should be stored.

Why you're pushing the base pointer is indeed a relevant question. You usually do that because you modify it afterwards, do stuff, and then pop it when you're done - which it seems you don't. It is usually used with functions that you call though. This might well be the problem here, you call inout a method, but you're using it as a label for jmp only. The code as you have posted it now has no chance of returning to where it was jmped to from.

Wikibooks has a fairly concise introduction to x86 stack frames.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top