汇编语言向堆栈传递8位和16位参数
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
.data
charVal BYTE 'x'
.code
push charVal ;语法错误!
call Uppercase
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 为和数一个过程的主调者必须保证它传递的参数与过程期望的参数是一致的。对堆栈参数而言,参数的顺序和大小都很重要!