c语言表达式3649的值是,汇编语言PROC伪指令:过程定义

32 位模式中,PROC 伪指令基本语法如下所示:

label PROC [attributes] [USES reglist], parameter_list

Label 是按照《LABEL伪指令》一节中说明的标识符规则、由用户定义的标号。Attributes 是指下述任一内容:

[distance] [langtype] [visibility] [prologuearg]

下表对这些属性进行了说明。

属性说明

distance

NEAR 或 FAR。指定汇编器生成的 RET 指令(RET 或 RETF)类型

langtype

指定调用规范(参数传递规范),如 C、PASCAL 或 STDCALL。能覆盖由 .MODEL 伪指令指定的语言

visibility

指明本过程对其他模块的可见性。选项包括 PRIVATE、PUBLIC (默认项)和 EXPORT。若可见性为 EXPORT,则链接器把过程名放入分段可执行文件的导出表。EXPORT 也使之具有了 PUBLIC 可见性

prologuearg

指定会影响开始和结尾代码生成的参数

参数列表

PROC 伪指令允许在声明过程时,添加上用逗号分隔的参数名列表。代码实现可以用名称来引用参数,而不是计算堆栈偏移量,如 [ebp+8]:

label PROC [attributes] [USES reglist],

parameter_1,

parameter_2,

...

parameter_n

如果参数列表与 PROC 在同一行,则 PROC 后面的逗号可以省略:

label PROC [attributes], parameter_1, parameter_2, ..., parameter_n

每个参数的语法如下:

paramName: type

ParamName 是分配给参数的任意名称,其范围只限于当前过程(称为局部作用域(local scope))。同样的参数名可以用于多个过程,但却不能作为全局变量或代码标号的名称。

Type 可以在这些类型中选择:BYTE、SBYTE、WORD、SWORD、DWORD、SDWORD、FWORD、QWORD 或 TBYTE。此外,type 还可以是限定类型(qualified type),如指向现有类型的指针。

下面是限定类型的例子:

PTR BYTE         PTR SBYTE

PTR WORD      PTR SWORD

PTR DWORD    PTR SDWORD

PTR QWORD    PTR TBYTE

虽然可以在这些表达式中添加 NEAR 和 FAR 属性,但它们只与更加专用的应用程序相关。限定类型还能够用 TYPEDEF 和 STRUCT 伪指令创建。

【示例 1】AddTwo 过程接收两个双字数值,用 EAX 返回它们的和数:

AddTwo PROC,

val1:DWORD,

val2:DWORD

mov eax,val1

add eax,val2

ret

AddTwo ENDP

AddTwo 汇编时,MASM 生成的汇编代码显示了参数名是如何被转换为 EBP 偏移量的。由于使用的是 STDCALL,因此 RET 指令附加了一个常量操作数:

AddTwo PROC

push ebp

mov ebp, esp

mov eax, dword ptr [ebp+8]

add eax, dword ptr [ebp+OCh]

leave

ret 8

AddTwo ENDP

用指令 ENTERO, 0 来代替下面的语句,AddTwo 过程也一样正确:

push ebp

mov ebp,esp

【示例 2】FillArray 过程接收一个字节数组的指针:

FillArray PROC,

pArray:PTR BYTE

...

FillArray ENDP

【示例 3】Swap 过程接收两个双字指针:

Swap PROC,

pValX:PTR DWORD,

pValY:PTR DWORD

Swap ENDP

【示例 4】Read_File 过程接收一个字节指针 pBuffer,有一个局部双字变量 fileHandle,并把两个寄存器保存入栈(EAX 和 EBX):

Read_File PROC USES eax ebx,

pBuffer:PTR BYTE

LOCAL fileHandle:DWORD

mov esi,pBuffer

mov fileHandle,eax

...

ret

Read_File ENDP

MASM 为 Read_File 生成的代码显示了在 EAX 和 EBX 入栈(由 USES 子句指定)前,如何为局部变量(fileHandle)预留堆栈空间:

Read_File PROC

push ebp

mov ebp,esp

add esp, OFFFFFFFCh ;创建 fileHandle

push eax ;保存 EAX

push ebx ;保存 EBX

mov esi, dword ptr [ebp+8] ; pBuffer

mov dword ptr [ebp-4],eax ; fileHandle

pop ebx

pop eax

leave

ret 4

Read_File ENDP

注意:尽管 Microsoft 没有采用这种方法,但 Read_File 生成代码的开始部分还可以是这样的:

Read_File PROC

enter 4,0

push eax

(etc.)

ENTER 指令首先保存 EBP,再将它设置为堆栈指针的值,并为局部变量保留空间。

由 PROC 修改的 RET 指令

当 PROC 有一个或多个参数时,STDCALL 是默认调用规范。假设 PROC 有 n 个参数,MASM 将生成如下入口和出口代码:

push ebp

mov ebp,esp

...

leave

ret (n*4)

RET 指令中的常数是参数个数乘以 4 ( 因为每个参数都是一个双字 )。若使用了 INCLUDE Irvine32.inc,则 STDCALL 是默认规范,它是所有 Windows API 函数调用使用的调用规范。

指定参数传递协议

一个程序可以调用 Irvme32 链接库过程,反之,也可以包含能被 C++ 程序调用的过程。为了提供这样的灵活性,PROC 伪指令的属性域允许程序指定传递参数的语言规范,并且能覆盖 .MODEL 伪指令指定的默认语言规范。

下例声明的过程采用了 C 调用规范:

Examplel PROC C,

parm1:DWORD, parm2:DWORD

若用 INVOKE 执行 Examplel,汇编器将生成符合 C 调用规范的代码。同样,如果用 STDCALL 声明 Examplel,INVOKE 的生成代码也会符合这个语言规范:

Examplel PROC STDCALL,

parm1:DWORD, parm2:DWORD

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值