Assembly MASM32中的混淆括号
我正在努力掌握MASM32,并对以下内容感到困惑: 我认为括号用于间接寻址,所以如果我有一个预定义的变量Assembly MASM32中的混淆括号,assembly,masm,masm32,Assembly,Masm,Masm32,我正在努力掌握MASM32,并对以下内容感到困惑: 我认为括号用于间接寻址,所以如果我有一个预定义的变量 .data item dd 42 然后 将“项目”的内容(即编号42)放入ebx和 mov ebx, [item] 将“项目”的地址(即42的存储位置)放入ebx 但控制台应用程序中的以下代码: mov ebx, item invoke dwtoa, ebx, ADDR valuestr invoke StdOut, ADDR valuestr mov ebx, [i
.data
item dd 42
然后
将“项目”的内容(即编号42)放入ebx和
mov ebx, [item]
将“项目”的地址(即42的存储位置)放入ebx
但控制台应用程序中的以下代码:
mov ebx, item
invoke dwtoa, ebx, ADDR valuestr
invoke StdOut, ADDR valuestr
mov ebx, [item]
invoke dwtoa, ebx, ADDR valuestr
invoke StdOut, ADDR valuestr
打印42次。要获取“项目”的地址,我似乎需要
mov ebx, [OFFSET item]
invoke dwtoa, ebx, ADDR valuestr
invoke StdOut, ADDR valuestr
谁能解释一下方括号在MASM中的作用,或者给我指出一个很好的参考资料。MASM对于具有类型的汇编语言来说是不寻常的。MASM之所以知道,是因为您如何定义符号
项
,它是类型为DWORD
的内存位置。当您将其用作操作数时,您知道(可能)您的意思是希望将值存储在地址,而不是地址的值。因此,使用item
或[item]
MASM并不重要,因为它假定您指的是后者。如果您确实需要项目的地址,则需要使用偏移项目
另一方面,如果使用item=42
将item
定义为常量,则mov ebx,item
将加载立即值。由于这种模糊性,您需要知道如何定义项
,以确定它是立即操作数还是内存操作数,最好避免使用裸符号作为操作数
我应该补充一点,当您仅使用符号或数字时,方括号[]
对MASM几乎没有任何意义。它们只有在与寄存器一起使用时才有意义。以下是一些例子:
item DD 42
const = 43
mov eax, item ; memory operand (the value stored at item)
mov eax, [item] ; memory operand
mov eax, OFFSET item ; immediate operand (the address of item)
mov eax, [OFFSET item] ; immediate operand
mov eax, const ; immediate operand (43)
mov eax, [const] ; immediate operand
mov eax, ds:[const] ; memory operand (the value at address 43)
mov eax, fs:30h ; memory operand (the value at address 30h + fs base)
mov eax, OFFSET const ; immediate operand
mov eax, [OFFSET const] ; immediate operand
mov eax, 42 ; immediate operand
mov eax, ebx ; register operand (the value of EBX)
mov eax, [ebx] ; indirect operand (the value pointed to by EBX)
因此,没有寄存器,方括号只显示您的意图。如果要将符号用作内存操作数,则应将其置于方括号内,并将
偏移量
与要用作立即数的符号一起使用 如果您使用mov eax、[esi+抵销项目]
,MASM会做什么?有效地址中存在寄存器是否会将其变为加载而不是mov r32、imm32?@PeterCordes寄存器和括号的组合使其成为内存操作数。因为有一个寄存器被添加到一个值中,所以括号是必需的。指令mov eax,esi+OFFSET item
是非法的,因为它不能被编码为立即数操作数或寄存器操作数,我相信您知道。如果要执行此指令所暗示的操作,请将项的偏移量添加到ESI中并存储在EAX中,您可以使用lea EAX、[ESI+偏移项]
。我还要加上moveax。[esi+item]
的意思与您的示例几乎相同,除非item
是一个标签,它必须是DWORD类型。我想我的意思是问它是一个加载还是一个语法错误,因为我真的很惊讶[OFFSET item]
是一个立即的。当然[esi+偏移项目]
不能是imm32
:P无论如何,好吧,所以这是一个加载,括号是必需的,谢谢。@PeterCordes我还原了您的编辑,因为它比您描述的要复杂一些。您最近关闭的问题中的问题是,跳转表标签是使用table:
定义的,使其成为近符号(或MASM的x64版本所称的任何符号)。如果它被定义为表QWORD…
,那么它将是一个QWORD符号,并将使用间接跳转。无论哪种方式,括号都没有区别,但符号的类型确实很重要。使用QWORD PTR可以通过更改地址类型来解决问题,但通常情况下这不是必需的。fs:30h
也是内存操作数,对吗?您只显示fs:[30h]
表单。[两个指令之间的差异:mov eax,dword ptr fs:[30h]和mov eax,在取消引用PEB时大fs:30h?])有一个mov eax,大fs:30h
(可能是IDA语法),OP因缺少[]
而混淆。(因此它可能是这个的重复)a还指出,var2 dword var1
汇编到var1
的地址。这是唯一明智的行为,因为var1
可能是extern
,使其内容在汇编时不可用。幸运的是,offset var1
在该上下文中是允许的,所以您可以始终使用明确的表示法。
item DD 42
const = 43
mov eax, item ; memory operand (the value stored at item)
mov eax, [item] ; memory operand
mov eax, OFFSET item ; immediate operand (the address of item)
mov eax, [OFFSET item] ; immediate operand
mov eax, const ; immediate operand (43)
mov eax, [const] ; immediate operand
mov eax, ds:[const] ; memory operand (the value at address 43)
mov eax, fs:30h ; memory operand (the value at address 30h + fs base)
mov eax, OFFSET const ; immediate operand
mov eax, [OFFSET const] ; immediate operand
mov eax, 42 ; immediate operand
mov eax, ebx ; register operand (the value of EBX)
mov eax, [ebx] ; indirect operand (the value pointed to by EBX)