64位汇编语言的编程艺术
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.12 调用C/C++过程

编写自定义的过程并对其加以调用,是一种非常有效的程序设计方式,但本章引入过程的原因并不是让用户编写自定义过程,而是训练用户具备调用C/C++过程(函数)的能力。编写自定义的过程,以将数据转换并输出到控制台是一项相当复杂的任务(目前为止可能远远超出用户的能力范围)。不过,用户可以调用C/C++语言中的printf()函数来生成程序输出,并在运行程序时验证程序是否确实在执行某些操作。

如果用户在汇编语言代码中调用printf(),而不提供printf()过程的定义,那么MASM会给出如下的错误信息:“使用了未定义的符号”。为了在源文件外部调用过程,需要使用MASM的externdef伪指令[9]。externdef伪指令的语法形式如下所示:

externdef symboltype

此处,symbol是用户想要定义的外部符号,type是该符号的类型(定义外部过程时,类型是proc)。为了在汇编语言源文件中定义printf()符号,可以使用以下语句:

externdef printf:proc

当定义外部过程符号时,应将externdef伪指令放在“.code”段中。

externdef伪指令不允许向printf()过程指定需要传递的参数,call指令也不提供指定参数的机制。取而代之的是,用户可以使用x86-64的寄存器RCX、RDX、R8和R9,向printf()函数传递最多4个参数。printf()函数要求第一个参数是格式字符串的地址。因此,在调用printf()之前,应该将字符串的地址加载到RCX寄存器,注意,该字符串以零结尾。如果格式字符串包含任何格式说明符(例如,%d),则必须在寄存器RDX、R8和R9中传递适当的参数值。第5章将详细讨论过程参数,包括如何传递浮点值以及4个以上的参数。