Assembly 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

我正在努力掌握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, [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)