8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

YASM/NASM x86 汇编中立即数与方括号的基本用法

admin 2月前

175 0

假设我有以下内容声明:section .bssbuffer resb 1 并且这些指令在section .text中遵循:mov al,5; mov-immediatemov [buffer],al ...

假设我有以下声明:

section .bss
buffer    resb     1

这些说明如下 section .text

mov    al, 5                    ; mov-immediate
mov    [buffer], al             ; store
mov    bl, [buffer]             ; load
mov    cl, buffer               ; mov-immediate?

我是否正确理解 bl 将包含值 5,而 cl 将包含变量的内存地址 buffer

我对以下两者之间的区别感到困惑

  • 将立即数移入寄存器,
  • 将寄存器移至立即数(输入的是数据还是地址?)
  • 将立即数移动到不带括号的寄存器中
    • For example, mov cl, buffer vs mov cl, [buffer]

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

  • mov edi, array 将数组第零索引的内存地址放入 edi 。即标签地址。
  • mov byte [edi], 3 将值 3 放入数组的第零索引中
  • 现在之后 add edi, 3 , edi 包含数组第三个索引的内存地址
  • mov al, [array] 将第零索引处的数据加载到 al .
  • mov al, [array+3] 将第三个索引处的数据加载到 al .
  • mov [al], [array] 无效,因为 x86 无法编码 2 个显式内存操作数 ,并且因为 al 只有 8 位,即使在 16 位寻址模式下也无法使用。 引用内存位置的内容。(x86 寻址模式)
  • mov array, 3 是无效的,因为您不能说“嘿,我不喜欢 array 存储的偏移量,所以我将其称为 3”。立即数只能是源操作数。
  • mov byte [array], 3 将值 3 放入数组的第零索引(第一个字节)。 The byte specifier is needed 符来避免带有内存、立即操作数的指令的字节/字/双字之间的歧义。否则,这将是一个汇编时错误(操作数大小不明确)。

如果其中任何一个是错误的,请指出。(编者注:我修复了语法错误/歧义,因此有效的语法实际上有效的 NASM 语法。并链接了其他问答以获取详细信息)

帖子版权声明 1、本帖标题:YASM/NASM x86 汇编中立即数与方括号的基本用法
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由admin在本站《loops》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 在标签“array”处保留一个零长度空间。如果您想要 .bss 部分中的十个字节条目数组,则应指定

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


    现在我来解释一下你提到的操作之间的区别:

    • p2

    • p3

    • p4


    因此, mov cl, buffer 将把 地址 到 cl(由于 cl 只有一个字节长,因此可能会或可能不会给出正确的地址),而 mov cl, [buffer] 将获得实际值。

    概括

    • 当你使用 [a] 时,你引用的是 a 指向的值。例如,如果 a 是 F5B1 中的地址 F5B1 RAM .
    • 标签是地址,即类似 F5B1 .
    • 存储在寄存器中的值不必以 [reg] 的形式引用,因为寄存器没有地址。事实上,寄存器可以被认为是立即值。
  • 我对汇编不太熟悉,但是在你顶部部分的中间要点中,最后一行汇编示例难道不应该反过来吗?即 mov [const], reg ?

  • @Coldblackice:mov [const], reg 是将数据存储在内存中,地址为 const。这个名字有点奇怪,但所有符号地址都是链接时常量。例如,您可以执行 dd const 来在某处(例如在数据部分)发出 4 字节绝对地址。或者 const 可以是数字地址,例如,如果您编写的代码处理固定内存地址上的旧硬件(如 VGA 内存)。例如,mov [0x0], ax 具有 DS 中的正确值。

  • 方括号本质上的作用类似于取消引用运算符(例如, * 在 C 语言中)。

    因此,

    mov REG, x
    

    x 的值移入 REG ,而

    mov REG, [x]
    

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

    至于你的问题:

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

    是的,你说得对。但要注意,由于 CL 只有 8 位宽,它只包含地址的最低有效字节 buffer .

  • 当您说“如果 x 是一个标签,则它的值就是该标签的地址”时,这是否意味着如果 x 的地址为 0x1234,那么当它是一个标签时的值也是 0x1234?

  • @InstructionPointer:在 MASM 语法中,mov eax, var 是加载,与 [var] 相同。在 NASM 语法中,mov eax, var 是标签地址的 mov-immediate。(MASM 语法 mov eax, OFFSET var)。如果您想要加载,请始终使用 mov eax, [var]` 以避免歧义。如果您想要地址,则没有可移植的语法可以明确表示地址。(除了在 x86-64 PIC 代码中,lea rdi, [var] 是最佳选择,假设 NASM 语法的默认 rel。除了 GAS .intel_syntax 需要 lea rdi, [var + rip] 作为相对于当前位置的地址...)

  • 您明白了。但是,有几个细节值得牢记:

    1. 地址可以并且通常大于 8 位所能容纳的内容( cl 是 8 位、 cx 是 16 位、 ecx 是 32 位、 rcx 是 64 位)。因此, cl 可能不等于变量的地址 buffer 。它只具有地址的最低有效 8 位。
    2. 如果有中断例程或线程可以抢占上述代码和/或访问 buffer ,则中的值 bl 可能与 5 不同。当损坏的中断例程无法保存寄存器值时,它们实际上可能会影响任何寄存器。
  • 不要忘记 ecx 仅在 386 或更高版本中可用,而 rcx 仅在 x86-64 中可用。

  • 对于所有使用立即数作为操作数将值写入 RAM 位置(或在其中进行计算)的指令,我们必须指定要访问多少个字节。因为我们的汇编无法知道我们是否只想访问一个 字节 、一个 两个字 ,例如,如果立即数是较低的值,如以下指令所示。

    array db 0FFh, 0FFh, 0FFh, 0FFh
    mov byte [array], 3
    

    结果:

    array db 03h, 0FFh, 0FFh, 0FFh
    

    ....

    mov word [array], 3
    

    结果:

    array db 03h, 00h, 0FFh, 0FFh
    

    ....

    mov dword [array], 3
    

    结果:

    array db 03h, 00h, 00h, 00h
    

    短剑

返回
作者最近主题: