3

I'm having trouble finding out the answer. From what I've read %ebp has 32-bits, moving %esp to %ebp you'll still have 32-bits, then subtract 70 to 32, and I don't understand the rest. I am new to this so I'm not very proficient. Please give a detailed explanation. Thank you!

Below is the question I am having trouble with.

At the end of this sequence of instructions, how many bytes separate esp and the stored return address on the program's stack? Assume that we called this function using standard 32-bit x86 calling conventions.

804847c functioname:
804847c: push %ebp
804847d: mov %esp,%ebp
804847f: sub $0x70,%esp
8048482: movl $0x0,0x4(%esp)
804848a: movl $0x8048580,(%esp)
Michael Petch
  • 46,082
  • 8
  • 107
  • 198
  • The `$0x70` value in this instruction `sub $0x70,%esp` is sign-extended to 32 bits, so it also has 32 bits, just as `esp` and `ebp` have. (although internally the `0x70` value is encoded in the instructions in only 8 bits, but that's not how it is used, that's only storage optimization in this particular case). Amount of bits used limits amount of different values which may be encoded in those bits, i.e. 8 bits can be interpreted as values from 0 to 255, or from -128 to +127, or as eight 1bit flags (on/off). In your question it doesn't matter much, as all involved values are 32b. – Ped7g Aug 15 '17 at 15:17

1 Answers1

1

sub $0x70,%esp : Reserve 0x70 bytes on the stack.

movl $0x0,0x4(%esp) : Place a zero 32-bit value as argument.

movl $0x8048580,(%esp) : Place an address. The next ret will jump to it.

By standard calling convention, named cdecl, arguments are placed on the stack followed by the address the callee should return to.

yacc
  • 2,915
  • 4
  • 19
  • 33
  • 1
    This doesn't seem right. _ESP_ has been adjusted downward by 0x70 (112 bytes). After the `sub` instruction the temporary copy of _EBP_ is at _ESP_ + 0x70, and the return address is at _ESP_ + 0x74 . 0x04(%esp) and (%esp) actually point to local variable area that was created on the stack with the `sub $0x70,%esp` instruction – Michael Petch Aug 15 '17 at 01:23
  • 2
    In my opinion the answer to the actual question is that the difference between _ESP_ and the return address is 0x70+ 0x04 (4 bytes for the push of _EBP_). That it 116 decimal or 0x74 hex. – Michael Petch Aug 15 '17 at 01:38
  • 1
    Should point out that the `movl` instructions - we don't know what they are intended to be used for. Their actual inclusion in the question don't actually alter the difference between _ESP_ and the return address. They are in fact just a red herring. This smells like a homework assignment so likely the instructor was hoping to confuse students with the last 2 instructions. – Michael Petch Aug 15 '17 at 01:48
  • @MichaelPetch Can you explain to me in detail how you came up with this answer? like why was the "sub $0x70,%esp" and "movl $0x0,0x4(%esp)" only ones used? why were the other ones not calculated? Thank you in advance, I really appreciate your input. – Kahrte_blanche Aug 15 '17 at 01:55
  • When function `functioname` is called the `call` instruction places the return address on the stack. After the call transfers to `functioname` _ESP_ points to the return address on the top of the stack. `push %ebp` decreases ESP by 4 and places a copy of EBP there. The next instruction that alters ESP is `sub $0x70,%esp`. This subtracts 0x70(112) from ESP. The two `movl` instructions don't alter _ESP_ at all so can be ignored. So when all the instructions are executed _ESP_ is 0x70+0x04=0x74 bytes from return address – Michael Petch Aug 15 '17 at 02:01
  • 0x74 is a hexadecimal number representing the value 116 decimal – Michael Petch Aug 15 '17 at 02:11