I'm writing a compiler - or something that looks like it - and I'm at the part where I generate simple, unoptimized assembly code.
The code works, except for one thing.
I understand that %esb
and %esp
work as follows in a function call:
Parameter #N -> N*4+4(%ebp)
Parameter 2 -> 12(%ebp)
Parameter 1 -> 8(%ebp)
Return Address -> 4(%ebp)
Old %ebp -> (%ebp)
Local Variable 1 -> -4(%ebp)
Local Variable 2 -> -8(%ebp) and (%esp)
However, the code below, which is output from my compiler, segfaults on the first line where I try to assign to -8(%esp)
in _start
. Doing the same thing in the twice
function does not segfault.
It seems to be that in the _start function I can't store 'local variables' on the stack, and I wonder how I should fix this?
The program:
.section .data
.section .text
.globl _start
.globl twice
.type twice, @function
twice:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
movl 8(%ebp), %ebx
addl %eax, %ebx
movl %ebx, -4(%ebp)
movl %ebx, %eax
movl %eax, -8(%ebp)
movl %eax, -8(%ebp)
end_twice:
leave
ret
_start:
movl $10, %eax
movl %eax, -8(%ebp)
movl $10, %eax
pushl %eax
call twice
addl $4, %esp
movl %eax, -8(%ebp)
movl %eax, %ebx
# Exit stuff.
movl $1, %eax
int $0x80
Original input:
int twice(int x)
{
return x+x;
}
int main()
{
int x;
x = 10;
x = multiply(x);
}
You'd typically, if using EBP as pointer to local stack frame, not write to where it's pointing to before calling the sub. instead, you'd simply push to ESP, and leave it to the sub to set up EBP accordingly, so you can read from where you pushed to ESP before. Your use of EBP, if using "traditional" stack frames, is therefore incorrect.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments