and esp, 0xfffffff0

前端 未结 3 1382
栀梦
栀梦 2020-12-31 02:39

I don\'t entirely understand the line with comment in it below. I read a few posts on SO and in the gcc manual and learned that it is for stack address alignmen

3条回答
  •  心在旅途
    2020-12-31 03:27

    It looks like it's part of some code to set up shop at the start of main.

    Function start: save the base frame pointer on the stack (needed by the leave instruction later):

       0x08048414 <+0>: push   ebp
    

    Now we align the stack pointer to a 16-byte bound, because the compiler (for whatever reason) wants it. This could be that it always wants 16-byte aligned frames, or that the local variables need 16-byte alignment (maybe someone used a uint128_t or they're using a type that uses gcc vector extensions). Basically, since the result will always be less than or equal to the current stack pointer, and the stack grows downward, it's just discarding bytes until it gets to a 16-byte aligned point.

       0x08048415 <+1>: mov    ebp,esp
       0x08048417 <+3>: and    esp,0xfffffff0
    

    Next we subtract 16 from the stack pointer, creating 16 bytes of local variable space:

       0x0804841a <+6>: sub    esp,0x10
    

    puts((const char*)0x8048510);

       0x0804841d <+9>: mov    DWORD PTR [esp],0x8048510
       0x08048424 <+16>:    call   0x8048320 
    

    system((const char*)0x8048520);

       0x08048429 <+21>:    mov    DWORD PTR [esp],0x8048520
       0x08048430 <+28>:    call   0x8048330 
    

    Exit the function (see another answer about what leave does):

       0x08048435 <+33>:    leave
       0x08048436 <+34>:    ret
    

    Example of "discarding bytes": say esp = 0x123C at the start of main. The first lines of code:

       0x08048414 <+0>: push   ebp
       0x08048415 <+1>: mov    ebp,esp
    

    result in this memory map:

    0x123C: (start of stack frame of calling function)
    0x1238: (old ebp value) <-- esp, ebp
    

    Then:

       0x08048417 <+3>: and    esp,0xfffffff0
    

    forces the last 4 bits of esp to 0, which does this:

    0x123C: (start of stack frame of calling function)
    0x1238: (old ebp value) <-- ebp
    0x1234: (undefined)
    0x1230: (undefined) <-- esp
    

    There's no way for the programmer to rely on a certain amount of memory being between esp and ebp at this point; therefore this memory is discarded and not used.

    Finally, the program allocates 16 bytes of stack (local) storage:

    Next we subtract 16 from the stack pointer, creating 16 bytes of local variable space:

       0x0804841a <+6>: sub    esp,0x10
    

    giving us this map:

    0x123C: (start of stack frame of calling function)
    0x1238: (old ebp value) <-- ebp
    0x1234: (undefined)
    0x1230: (undefined)
    0x123C: (undefined local space)
    0x1238: (undefined local space)
    0x1234: (undefined local space)
    0x1230: (undefined local space) <-- esp
    

    At this point, the program can be sure there are 16 bytes of 16-byte aligned memory being pointed to by esp.

提交回复
热议问题