CSAPP confuse with pushtest result Practice Problem 4.7

263 views Asked by At

Y86 is similar to x86-64. Why function pushtest always returns zero?

As I know on x86-64 Push decrements the ESP register first than writes. Pop read first than increments the ESP register.

    .text
.globl pushtest
pushtest:
    movq    %rsp, %rax
    pushq   %rsp
    popq    %rdx
    subq    %rdx, %rax
    ret
2

There are 2 answers

0
Renat On

First. You should not modify %rsp (which is Stack Pointer register) manually, don't do movq %rsp, .... The %rsp is (and must only be) managed by push, pop, call, ret. Check also this question.

Then it's always %rdx==0 at the end, because:

movq    %rsp, %rax  ; %rsp==%rax
pushq   %rsp        ; top of the stack := %rsp == %rax
popq    %rdx        ; %rdx := top of the stack == %rax
subq    %rdx, %rax  ; %rdx := %rdx - %rax , i.e. %rdx := %rax - %rax == 0
0
Jason On

I reference This answer the "pushq" can be replaced by "subq and movq", "popq" can be replace d by "movq and addq".

But "PUSH ESP" and "POP ESP" are the special case. Reference This answer. But result not "0"

pushq %rsp ;pushes the value of the ESP register as it existed before the instruction was executed.

popq %rsp ;increments the stack pointer (ESP) before data at the old top of stack is written into the destination.

pushq %rdx ;Decrements the stack pointer and then stores the source operand on the top of the stack.

popq %rdx ;Loads the value from the top of the stack to the location specified with the destination operand (or explicit opcode) and then increments the stack pointer.

rax =
rdx =

0x28 |  0x12  |
0x30 |  0x34  | <--- rsp
0x38 |  0x56  |
0x40 |  0x78  |
0x48 |  0x9A  |


movq    %rsp, %rax
rax = 0x30
rdx =

0x28 |  0x12  |
0x30 |  0x34  | <--- rsp
0x38 |  0x56  |
0x40 |  0x78  |
0x48 |  0x9A  |


pushq   %rsp ;store, using rsp as the address, then subtract 8 from rsp
rax = 0x30
rdx =

0x28 |  0x12  | <--- rsp
0x30 |  0x30  |
0x38 |  0x56  |
0x40 |  0x78  |
0x48 |  0x9A  |


popq    %rdx ;load, using rsp as the address, then add 8 to the rsp
rax = 0x30
rdx = 0x30

0x28 |  0x12  | <--- rsp
0x30 |  0x30  |
0x38 |  0x56  |
0x40 |  0x78  |
0x48 |  0x9A  |

subq    %rdx, %rax    ;Return 0
rax = 0x00
rdx = 0x30

0x28 |  0x12  |
0x30 |  0x30  | <--- rsp
0x38 |  0x56  |
0x40 |  0x78  |
0x48 |  0x9A  |