-
EAX -
EBX -
ECX -
EDX -
EDI -
ESI -
EBP -
ESP
example.s
经过简化以后,大概是下面的样子。add_a_and_b
和main
,对应两个标签_add_a_and_b
和_main
。每个标签里面是该函数所转成的 CPU 运行流程。push
是 CPU 指令,%ebx
是该指令要用到的运算子。一个 CPU 指令可以有零个到多个运算子。push
指令用于将运算子放入 Stack,这里就是将3
写入main
这个帧。push
指令其实有一个前置操作。它会先取出 ESP 寄存器里面的地址,将其减去4个字节,然后将新地址写入 ESP 寄存器。使用减法是因为 Stack 从高位向低位发展,4个字节则是因为3
的类型是int
,占用4个字节。得到新地址以后, 3 就会写入这个地址开始的四个字节。push
指令将2
写入main
这个帧,位置紧贴着前面写入的3
。这时,ESP 寄存器会再减去 4个字节(累计减去8)。7.3 call 指令
call
指令用来调用函数。add_a_and_b
函数。这时,程序就会去找_add_a_and_b
标签,并为该函数建立一个新的帧。_add_a_and_b
的代码。_add_a_and_b
这个帧。这是因为后面要用到这个寄存器,就先把里面的值取出来,用完后再写回去。push
指令会再将 ESP 寄存器里面的地址减去4个字节(累计减去12)。7.4 mov 指令
mov
指令用于将一个值写入某个寄存器。2
,再将2
写入 EAX 寄存器。3
,将其写入 EBX 寄存器。7.5 add 指令
add
指令用于将两个运算子相加,并将结果写入第一个运算子。7.6 pop 指令
pop
指令用于取出 Stack 最近一个写入的值(即最低位地址的值),并将这个值写入运算子指定的位置。pop
指令还会将 ESP 寄存器里面的地址加4,即回收4个字节。7.7 ret 指令
ret
指令用于终止当前函数的执行,将运行权交还给上层函数。也就是,当前函数的帧将被回收。add_a_and_b
函数终止执行,系统就回到刚才main
函数中断的地方,继续往下执行。pop
操作已经回收了4个字节,这里再回收8个字节,等于全部回收。main
函数运行结束,ret
指令退出程序执行。原文始发于微信公众号(汇编语言):【汇编语言】入门教程
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论