[var]和var

时间:2016-09-13 15:56:21

标签: assembly x86 nasm

我正在学习汇编程序并且到达了我实际上不知道[variable]variable之间差异的地步。正如教程所说,两者都是指针,那么这有什么意义呢?为什么我必须在type Identifier之前使用[]? 我的汇编程序:nasm x86_64 running on Linux--> Ubuntu

3 个答案:

答案 0 :(得分:8)

在x86中,英特尔语法expression表示地址expression的内存内容。

没有括号的

mov eax,variable ; moves address of variable into eax lea eax,[variable] ; equivalent to the previous one (LEA is exception) mov eax,[variable] ; moves content of variable into eax 取决于您正在使用的汇编程序。

NASM:

mov eax,variable   ; content of variable (for lazy programmers)
mov eax,OFFSET variable   ; address of variable
lea eax,[variable] ; address of variable
mov eax,[variable] ; content of variable

MASM(TASM):

variable

GAS(AT& T语法):我不打扰,它不是英特尔语法。

在所有情况下,variable1 db 41 variable2 dw 41 label1: 都是符号标记内存中特定位置的别名,标签出现在该位置。所以:

variable1

在符号表中生成三个符号,variable2label1mov eax,<symbol>

当您在代码中使用其中任何一个时,例如db,它没有关于它是由dw还是mov [variable1],ebx定义的信息还是作为标签,因此它不会给您执行mov [ebx],eax ; obviously 32 bits are stored, because eax is 32b wide mov [ebx],1 ; ERROR: how "wide" is that immediate value 1? mov [ebx],WORD 1 ; NASM syntax (16 bit value, storing two bytes) mov WORD [ebx],1 ; NASM syntax (16 bit value, storing two bytes) mov WORD PTR [ebx],1 ; MASM/TASM syntax 时覆盖任何警告(覆盖定义的第一个字节之外的3个字节)。

它只是内存中的一个地址。

当不能从指令操作数本身推导出类型时,必须在大多数汇编程序 中使用类型标识符。

    zone.js:484 Unhandled Promise rejection: Template parse errors:
    Can't bind to 'ngModel' since it isn't a known property of 'datepicker'.
    ("
    </div>
    <div class="form-input">
        <datepicker [ERROR ->][(ngModel)]="notice.date"></datepicker>
    </div>
  </div>
    "): AddNoticeComponent@17:24 ; Zone: <root> ; Task: Promise.then ; Value: 

答案 1 :(得分:4)

使用寄存器和指针的一个小例子:

mov eax, 10表示:在EAX中移动值10.在这种情况下,EAX仅用于存储内容。 EAX包含的内容对程序员来说无关紧要,因为它无论如何都会被删除。

mov [eax], 10表示:将值10 移动到存储在EAX寄存器中的地址。在这种情况下,存储在EAX中的值对我们很重要,因为它是指针,这意味着我们必须去EAX寄存器并查看包含的内容,然后我们将此值用作地址访问。

使用指针时需要两个步骤:

  1. 转到EAX,查看它包含的值(例如EAX = 0xBABA);

  2. 转到EAX的地址指向(在我们的案例中为0xBABA)并在其中写入10。

  3. 当然,指针不一定与寄存器一起使用,这个小例子只是为了解释它是如何工作的。

答案 2 :(得分:1)

由于您已经了解C ++,我将通过向您展示这些表达式的C等价物来回答。

写作时

[variable]

在汇编中,它等同于

*variable
C中的

即,将variable视为指针并取消引用指针 - 获取指针指向的值。

同样,&#39;类型标识符&#39;就像将指针转换为不同的类型:

ASM:
    dword ptr [variable]
C:
    *((uint32_t*) variable)

ASM:
    word ptr [variable]
C:
    *((uint16_t*) variable)

我希望这有助于您理解这些表达的含义。

(此部分是指从原始问题中删除的附录)

我不完全确定您在转换为ascii&#39;时遇到了什么问题,但我怀疑您只是对它在视觉上呈现方式感到困惑在输出或其他东西。

例如,如果你有这样的代码:

myInteger db 41
mov AL, byte ptr [myInteger]

mov会将值41从内存复制到AL寄存器中。数字41恰好是)字符的ascii表示,但这并没有改变任何内容。该值是否被解释为ascii字符或整数取决于您,因为它们是相同的值。