x86 Assembly和yasm中immediates(方括号)的基本用法

Inv*_*ion 28 x86 assembly nasm memory-address yasm

假设我声明了以下内容:

section .bss
buffer    resb     1
Run Code Online (Sandbox Code Playgroud)

这些说明如下:

mov    al, 5                    ; mov-immediate
mov    [buffer], al             ; store
mov    bl, [buffer]             ; load
mov    cl, buffer               ; mov-immediate?
Run Code Online (Sandbox Code Playgroud)

我是否理解bl将包含值5,并且cl将包含变量的内存地址section .text

我对两者之间的差异感到困惑

  • 立即进入登记册,
  • 将寄存器移动到立即(进入的是什么,数据或地址?)和
  • 在没有括号的情况下立即移动到寄存器中
    • 例如,buffervsmov cl, buffer

更新:阅读回复后,我认为以下摘要是准确的:

假设声明mov cl, [buffer]存在于mov edi, array.我的理解是:

  • edi将第0个数组索引的内存地址放入mov byte [edi], 3.
  • add edi, 3 将VALUE 3放入数组的第0个索引中
  • 之后edi,mov al, [array]现在包含数组第3个索引的内存地址
  • al将DATA置于第零个索引中mov al, [array+3].
  • al将DATA放在第三个索引处mov [al], [array].
  • al 无论出于何种原因,都无效.
  • mov array, 3是无效的,因为你不能说"嘿,我不喜欢array存储的偏移,所以我称之为3"
  • mov byte [array], 3 将值3放入数组的第0个索引中.

如果其中任何一个是假的,请提及.

Job*_*Job 21

方括号基本上像解引用运算符一样工作(例如,*在C中).

所以,像

mov REG, x
Run Code Online (Sandbox Code Playgroud)

将值x移入REG,而

mov REG, [x]
Run Code Online (Sandbox Code Playgroud)

移动x指向的内存位置的值REG.请注意,如果x是标签,则其值是该标签的地址.

至于你的问题:

我是否理解bl将包含值5,并且cl将包含变量缓冲区的内存地址?

是的,你是对的.但要注意,因为CL只有8位宽,所以它只包含地址的最低有效字节buffer.


byr*_*sos 15

实际上,你的想法是正确的.也就是说,bl将包含5和cl缓冲区的内存地址(实际上标签缓冲区本身就是一个内存地址).


现在,让我解释一下您提到的操作之间的差异:

  • 将立即数移入寄存器可以使用.mov reg,imm可能令人困惑的是标签例如缓冲区本身是包含地址的立即值.

  • 你真的不能动寄存器到直接,因为眼前的值是常量,像2FF1Ah.什么,你可以做的是移动寄存器其中常数点to.You能做到这一点喜欢的地方mov [const], reg.

  • 您也可以使用间接寻址,例如mov reg2,[reg1]将reg1指向有效位置,并将reg1指向的值传递给reg2.


因此,mov cl, buffer将缓冲区的地址移动到cl(可能会或可能不会给出正确的地址,因为cl只有一个字节长),而 mov cl, [buffer]将得到实际值.

摘要

  • 当使用并[a],则参考值在其中点to.For例如,如果是的地方F5B1,然后[A]是指在地址F5B1 RAM.
  • 标签是地址,即值等F5B1.
  • 存储在寄存器中的值不必被引用为[reg],因为寄存器没有地址.实际上,寄存器可以被认为是立即值.


Ale*_*nze 6

你明白了。但是,有一些细节需要牢记:

  1. 地址通常可以大于8位可以容纳的地址(cl8位,cx16位,ecx32位,rcx64位)。因此,cl可能不等于变量的地址buffer。它只有地址的最低8位。
  2. 如果存在可以抢占上述代码和/或访问的中断例程或线程,则中buffer的值bl可能不同于5。中断的中断例程在无法保存寄存器值时实际上可能会影响任何寄存器。