質問

I have to work with x86 for a homework assignment. I keep getting this segfault for an atoi call, but I'm not sure why it's occurring. This is the code:

    addl    $4, %eax
    movl    (%eax), %eax
    movl    %eax, (%esp)
    call    atoi

Where $eax right before the "call atoi" equals "11". To prove it, this is what I get in gdb right before the call.

  x/s $eax
  0xffffd658:    "11"

I guess my big question is what should be held in register $eax before the "call atoi" and what would $eax have to hold for the program to then segfault in the "call atoi"?

EDIT: Someone asked for the registers.

  (gdb) x/s $eax
  0xffffd658:    "11"
    (gdb) n

Program received signal SIGSEGV, Segmentation fault.
0x2aaaaaa3 in ?? ()
(gdb) inf r
eax            0x0  0
ecx            0x2aaaaaab   715827883
edx            0x0  0
ebx            0x2c3ff4 2899956
esp            0xffffd458   0xffffd458
ebp            0x80484ef    0x80484ef
esi            0x0  0
edi            0x0  0
eip            0x2aaaaaa3   0x2aaaaaa3
eflags         0x10287  [ CF PF SF IF RF ]
cs             0x23 35
ss             0x2b 43
ds             0x2b 43
es             0x2b 43
fs             0x0  0
gs             0x63 99
(gdb) 
役に立ちましたか?

解決

It depends on whether your atoi function expects the pointer in %eax or on the stack. You seem to be undecided about that, given the code segment:

movl    %eax, (%esp)
call    atoi

If that's supposed to be pushing the address on to the stack, you either need to really push it (which modifies the stack pointer correctly) or modify the stack pointer yourself (such as with sub %esp, 4 or something).

The x86 stack pointer points to the last pushed entry so that push will first decrement the stack pointer then store the value at the new pointer. That means movl %eax (%esp) is going to corrupt the last pushed entry on the stack rather than place a new value on the stack.

Most people let the CPU handle the stacking of data rather than trying to do it manually, so you're probably looking for:

push %eax

However, if instead atoi expects its argument in %eax rather than on the stack, why would you write it to the stack? That's still going to corrupt whatever was there.

So, the first thing I would do would be choose either (for a pushed value):

addl    $4, %eax
movl    (%eax), %eax
push    %eax
call    atoi

or (for using %eax), just:

addl    $4, %eax
movl    (%eax), %eax
call    atoi
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top