我对PTR运算符有一点问题,我可以轻松地将大内存转移到下面的小寄存器示例中:
ax = small register which is 2 byte
memory = variable which is 4 byte
.data
variable dword 05010h
.code
mov ax,WORD PTR variable
它会正常工作。
现在我的问题是我不明白为什么我不能将像eax
这样的大寄存器移动到一个2字节的小内存变量中?
示例:
.data
variable word ?
.code
mov eax, 01050h
mov variable, word ptr eax
说:Error invalid use of register
注意:如果大小匹配,它可以正常工作
答案 0 :(得分:2)
问题是你显然不知道以下指令的作用:
mov ax, word ptr variable
该指令不读取32位变量并将变量写入16位寄存器!
但是它做了什么?
通常,CPU不知道哪个数据类型存储在某个内存位置。地址variable
的内存可能包含以下字节:
01h 02h 03h 04h
这可以是四个8位变量,两个16位变量(值为201h和403h),一个32位变量,值为4030201h,甚至一个16位和两个8位变量。
因为CPU不知道哪种变量存储在内存中,所以由程序员(或编译器)以16位变量的方式编写汇编程序被访问为16位变量。
指令mov ax, variable
表示:"位置(地址)variable
的RAM中有一个16位变量。读取它并将其写入ax
寄存器。"
CPU会这样做。因为内存中包含字节01h 02h 03h 04h
,所以它将读取两个字节01h 02h
并将它们解释为16位变量(值为201h)。
使用所谓的" little-endian" CPU(如x86)这将导致"正确"当32位变量具有"小"值,因为该指令将有效地读取32位变量的低16位。
顺便说一句:使用" big-endian" CPU(如PowerPC)即使这样也不会再工作了,因为32位变量的高位(而不是低位)将被读取。
当然,您也可以将包含16位变量的存储单元读入32位寄存器:
mov eax, variable
让我们在上面的示例中说01h 02h 03h 04h
是两个16位变量,其值为201h和403h。如果您将此RAM存储器读取为32位值,则结果为4030201h,而不是201h!
x86 CPU(自80386起)有两条指令movsx
(符号扩展高位)和movzx
(将高位设置为零),用于将较小的值复制到较大的寄存器中
这些说明可以让您正确地"将16位值读入32位寄存器。
修改强>
根据Peter Cordes的说法,MASM在dword ptr
中明确要求mov eax, dword ptr variable
,因为MASM将检查variable
是否真的是32位并打印错误消息。
对于CPU,指令mov eax, variable
和mov eax, dword ptr variable
的指令完全相同。
mov variable, word ptr eax
它说:
Error invalid use of register
该指令可能(我不确定因为我不使用MASM)被命名为:
mov dword ptr variable, eax
但是你应该知道这条指令会做什么:它将覆盖内存中的32位:variable
和内存中variable
之后的数据。我怀疑这是你真正想做的事。
如果你想"转换"将32位值转换为16位值,如下面的C代码:
variable16 = (unsigned short)variable32;
......以下汇编代码将完成这项工作:
mov eax, variable32
mov variable16, ax
...因为ax
是eax
的低16位。