assembly 有没有办法用MOV代替PUSH来设置函数调用的参数?

waxmsbnn  于 2022-11-13  发布在  其他
关注(0)|答案(3)|浏览(126)

在x86汇编中,在通常的32位调用约定中,通常使用push函数参数,然后使用add清理堆栈。是否有任何有用的替代方法,例如使用MOV代替PUSH
例如,有没有其他有效的方法来执行以下操作?

PUSH   10
PUSH   20
CALL   plus     ; int plus(int,int) adds two integer args, leaving EAX = 30
add    esp, 8
bqjvbblv

bqjvbblv1#

sub rsp, 8
mov dword ptr[rsp+4], 10
mov dword ptr[rsp], 20
call plus

这与您的代码执行完全相同的操作,但没有使用push;假定推入被定义为“将堆栈指针递减操作数大小,然后将操作数移动到堆栈指针所指向的位置”,那么“转译”是直接的。

ao218c7q

ao218c7q2#

在这个问题的原始版本中,OP提到了AMD 64。x86-64上的常见调用约定在寄存器中传递前几个参数(像一些32位约定,如MS的vectorcall),而不是在堆栈上传递,所以当然在那里使用mov

mov   edi, 10     ; x86-64 SysV calling convention.
mov   esi, 20
call  plus        ; leaves eax = 30.

如果您正在编写只从asm调用的函数,则可以在每个函数的基础上制定自定义调用约定,这样即使是32位也可以使用类似上面的代码。(但是我建议选择在常规ABI中不保留调用的寄存器。例如,在函数上使用__attribute__((regparm(3)))gcc -m32会使它接受EAX、EDX、ECX请参阅x86标签wiki以获取ABI文档的链接。

取代push以将参数放在堆栈上

如果ESP上面还有空间,你可以将mov放到那个空间,而不是推送args。
例如,对于两个背靠背的call,你可以使用mov来写入新的参数,而不是使用add esp, 8/ push / push来清理堆栈并压入新的参数。GCC does this with -maccumulate-outgoing-args),这是一些-mtune=设置启用的。
(实际上,gcc的-maccumulate-outgoing-args稍有不同。它在使用sub的第一次调用之前为args预留了空间,因此即使第一次调用也不使用push。这增加了代码大小,但最大限度地减少了对esp的更改,因此它缩小了将指令地址Map到堆栈帧大小的CFI元数据,用于-fomit-frame-pointer的堆栈展开目的。在推入速度较慢的旧CPU上,避免使用它。)

;; Delayed arg popping.  Push is cheap since Pentium-M stack engine so we use it for the first call
push     10
push     20
call     foo
; add esp,8   ; don't do this yet, using mov instead of push
; then like gcc -maccumulate-outgoing-args
mov      dword [esp+4], 15
mov      [esp], eax
call     bar
add      esp,8                ; NOW pop the args.

这会执行bar( foo(20,10), 15),并使堆栈指向与开始之前相同的位置。弹出堆栈(使用add),然后使用push输入新的参数,在现代CPU上可能会做得更好。这节省了指令,但不节省代码大小。它可能会节省1个uop。
在Intel的堆栈引擎上,在mov [esp+4]add esp, 4之前需要一个额外的堆栈同步微操作,因此前端微操作的开销是相同的。避免这种情况的唯一方法是推送新参数。最后再做一次大清理(add esp, 16)。但是这会因为接触新的堆栈空间而导致更多的缓存未命中。(参见x86标签wiki以获得更多优化文档)。
这确实最小化了微操作高速缓存的微操作计数;堆栈同步微操作是动态生成的。但是mov往往比push大,特别是对于小的立即数(2字节push 1与8字节mov dword [esp+4], 1),因此使用add esp,8/ 2x push时,I缓存的占用空间可能更好。

nhhxz33t

nhhxz33t3#

就像这样:mov eax [value]祝你在汇编编程方面好运,这很难。

相关问题