FromNandの日記

自分的備忘録

【x86アセンブラ】PUSH・POPの動作を少し細かく見てみる

今回考えるのは、PUSH・POPにおいてESPの変化と値を取り出すタイミングがどの順番で行われているかということだ。


実験に使用するコードはこれ。

.code32

.globl push_test, pop_test

.text

push_test:
    subl $4, %esp               ## here!
    movl $0x12345678, (%esp)    ## here!
    popl %eax
    ret

pop_test:
    pushl $0x12345678
    movl (%esp), %eax           ## here!
    addl $4, %esp               ## here!
    ret


C言語からは次のように呼び出す。
printというのは自作のprintf関数だ。

unsigned int push_test();
unsigned int pop_test();

int main(int argc, char **argv, char **envp){
    print("push_test() = %x, pop_test() = %x\n", push_test(), pop_test());
    return 0;
}


実行結果は次のようになった。

push_test() = 12345678, pop_test() = 12345678


この結果から、PUSH・POPを行う直前のESPは最後に操作した値を指しているということがわかる。
最後にPUSH・POPを模倣したコードを載せておく。


PUSH

subl $4, %esp
movl 値, (%esp)


POP

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