- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
为什么我们有push和pop这样的命令?
据我了解,pop
和 push
基本上与执行 a (mov
then add
) 相同和 (sub
then mov
) 分别在 esp
上。
例如不会:
pushl %eax
相当于:
subl $4, %esp
movl %eax, (%esp-4)
如果堆栈访问不是(%esp-4)
,请纠正我,我仍在学习汇编
我能看到的唯一真正的好处是同时执行这两项操作是否会带来一些优势;但我不明白怎么会这样。
最佳答案
但是,也没有理由使用 CALL
指令。毕竟,您可以使用以下方式模拟调用:
sub esp,4
mov [esp-4], offset return_address
jmp myproc
也不需要 RET
指令,因为您可以使用以下命令来模拟它:
mov eax,[esp]
add esp,4
jmp [eax]
如果您仔细观察,您会发现许多可以通过组合其他指令来模拟的指令。有什么意义?
这些类型问题的答案 Root 于 x86 处理器系列及其之前的处理器的悠久历史。设计人员研究了程序员如何使用处理器,并创建了在执行速度和内存使用方面高效的指令集。
在 70 年代末,64 KB 的 RAM 已经很大了,而且 RAM 的速度要慢得多。每个指令字节都很宝贵,仅仅从内存中获取指令就会产生巨大的开销。指令获取时间比执行时间长的情况并不少见。因此,通过用尽可能少的指令字节进行编码,可以获得巨大的性能提升。
与 CPU 时钟速度相比,RAM 的速度仍然慢得令人难以置信,因此通过尽可能少的指令字节进行编码仍然可以获得好处。确实,我们拥有的大型 CPU 缓存有很大帮助,分支预测和预取逻辑也有很大帮助,但从 RAM 传输到 CPU 缓存的每个字节仍然很昂贵。节约指令编码是值得的。
关于调用过程:
用汇编语言调用过程的标准方法是推送参数,然后调用
该过程。例如,这传递两个双字值:
push eax
push ebx
call proc ; pushes the return address and jumps to proc
...
proc:
; at this point, [esp] contains the return address
ret
指令将返回地址弹出到指令指针中。
当然,必须有人清理堆栈。调用者可以通过递增堆栈指针来清理堆栈。或者被调用的过程可以使用ret 8
清理堆栈,这将弹出返回地址并递增堆栈指针。
参见http://www.delorie.com/djgpp/doc/ug/asm/calling.html有关调用约定的更多信息。
关于assembly - CPU 上压入和弹出操作的必要性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10155692/
我是一名优秀的程序员,十分优秀!