PTR的作用有点像C语言的指针类型强制转换,比如定义一个DWORD,想用MOV指令将其低位2字节传入AX中,但汇编器会报类型不匹配的错误,使用PTR就能解决此问题。PTR的格式如下
数据类型伪指令 PTR 变量名称/地址表达式
如 【WORD PTR X1】就是将X1代表的变量强制转换成WORD类型。
为什么说PTR是伪指令。之前介绍过伪指令是指汇编器汇编时使用的指令符号,伪指令不对应任何机器指令。见以下例程
.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO,dwExitCode:DWORD
.data
X1 DWORD ?
X2 WORD ?
X3 BYTE ?
.code
MAIN PROC
MOV EAX,OFFSET X1
MOV X1,12345678h
MOV WORD PTR X1,0ABCDh
MOV X2,0ABCDh
MOV WORD PTR [EAX],5678h
MOV X3,0EFh
MOV BYTE PTR X2,0EFh
INVOKE ExitProcess,0
MAIN ENDP
END MAIN
之前介绍过同样的汇编指令,其目的操作数不同,翻译成的机器指令也是不同的。
比如MOV指令,如果目的操作数是内存DWORD变量,其翻译后的机器指令为【C7 05】。如果目的操作是内存WORD变量,翻译后的机器指令为【66 C7 05】。如果目的操作是内存BYTE变量,翻译后的机器指令为【C6 05】
下面是上段程序汇编后的结果
源代码:MOV EAX,OFFSET X1
机器指令:B8 00 40 0F 01 mov eax,offset X1 (010F4000h)
源代码:MOV X1,12345678h
机器指令:C7 05 00 40 0F 01 78 56 34 12 mov dword ptr [X1 (010F4000h)],12345678h
源代码:MOV WORD PTR X1,0ABCDh
机器指令:66 C7 05 00 40 0F 01 CD AB mov word ptr [X1 (010F4000h)],0ABCDh
源代码:MOV X2,0ABCDh
机器指令:66 C7 05 04 40 0F 01 CD AB mov word ptr [X2 (010F4004h)],0ABCDh
源代码:MOV WORD PTR [EAX],5678h
机器指令:66 C7 00 78 56 mov word ptr [eax],5678h
源代码:MOV X3,0EFh
机器指令:C6 05 06 40 0F 01 EF mov byte ptr [X3 (010F4006h)],0EFh
源代码:MOV BYTE PTR X2,0EFh
机器指令:C6 05 04 40 0F 01 EF mov byte ptr [X2 (010F4004h)],0EFh
源代码:INVOKE ExitProcess,0
机器指令:6A 00 push 0
机器指令:E8 0E 00 00 00 call _ExitProcess@4 (010F1059h)
从汇编结果可以看出【MOV WORD PTR X1,0ABCDh】【MOV X2,0ABCDh】中的【MOV】都被翻译成了机器指令【66 C7 05】。这也证明了PTR其实是告诉汇编器无论目的操所数的类型是什么,就将其视为WORD类型,将MOV翻译成【66 C7 05】。
PTR并不对应任何机器指令
代码中【MOV WORD PTR [EAX],5678h】表示将5678赋值到EAX的值所代表的内存地址中,将内存地址视为WORD类型