c语言参数传递 堆栈,汇编语言向堆栈传递8位和16位参数

在32位模式中,向过程传递参数时,为保持堆栈对齐和优化性能,通常需要将8位或16位操作数扩展为32位。博客中通过示例说明了如何正确地使用PUSH和MOVZX指令来扩展参数,确保调用过程如Uppercase和AddTwo时不会出错。主要强调了参数顺序、大小的重要性以及堆栈对齐对于避免页面失效和提高运行效率的关键作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

32 位模式中,向过程传递堆栈参数时,最好是压入 32 位操作数。虽然也可以将 16 位操作数入栈,但是这样会使得 EBP 不能对齐双字边界,从而可能导致出现页面失效、降低运行时性能。因此,在入栈之前,要把操作数扩展为 32 位。下面的 Uppercase 过程接收一个字符参数,并用 AL 返回其大写字母:

Uppercase PROC

push ebp

mov ebp, esp

mov al, [esp+8 ] ;AL=字符

cmp al, 'a' ;小于'a' ?

jb L1 ;是:什么都不做

cmp al, 'z' ;大于'z' ?

ja L1 ;是:什么都不做

sub al, 32 ;否:转换字符

L1:

pop ebp

ret 4 ;清除堆栈

Uppercase ENDP

当向 Uppercase 传递一个字母字符时,PUSH 指令自动将其扩展为 32 位:

push 'x'

call Uppercase

如果传递的是字符变量就需要更小心一些,因为 PUSH 指令不允许操作数为 8 位:

.data

charVal BYTE 'x'

.code

push charVal                                  ;语法错误!

call Uppercase

相反,要用 MOVZX 把字符扩展到 EAX:

movzx eax,charVal                         ;扩展并传送

push eax

call Uppercase

16 位参数示例

假设现在想向之前给出的 AddTwo 过程传递两个 16 位整数。由于该过程期望的数值为 32 位,所以下面的调用会发生错误:

.data

word1 WORD 1234h

word2 WORD 4111h

.code

push word1

push word2

call AddTwo ;错误!

因此,可以在每个参数入栈之前进行全零扩展。下面的代码将会正确调用 AddTwo:

movzx eax,word1

push eax

movzx eax,word2

push eax

call AddTwo ; EAX 为和数

一个过程的主调者必须保证它传递的参数与过程期望的参数是一致的。对堆栈参数而言,参数的顺序和大小都很重要!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值