【问题标题】:Indirect Register Addressing间接寄存器寻址
【发布时间】:2025-11-25 22:40:02
【问题描述】:

我试图弄清楚寄存器间接寻址是如何工作的。我有一个存储 5 值的变量,如下所示:

section .data

number db 53 ; ascii code for 5

section .bss
number2 resb 1
section .text
global _start

_start:

mov eax,number
mov number2,[eax]

在代码的最后两行,我实际上想要做的是让 eax 充当指向存储在 number 的数据的指针,然后将此数据移动到 number2 变量中。我虽然间接寄存器寻址是通过 [register] 完成的,但我的代码似乎不起作用。任何有关语法的帮助将不胜感激。

【问题讨论】:

    标签: unix assembly nasm addressing-mode


    【解决方案1】:

    标签在 nasm 中用作地址,因此您的 mov number2, [eax] 将转换为 mov 0x12345678, [eax] 之类的东西,这当然是无效的,因为您无法将数据移动到立即操作数。所以你需要mov [number2], [eax],但这也是无效的。

    您可以使用一些寄存器来临时保存值[eax]

    mov eax, number
    mov dl, [eax]
    mov [number2], dl
    

    【讨论】:

    • 啊,谢谢,我还是不太明白为什么你需要那个中间步骤(dl 步骤)并且不能只在地址中获取数据并将其直接存储在数字中,即 [number2] ,[eax],为什么我们需要在将其移动到变量之前将其转移到另一个寄存器,这让我感到困惑。感谢您的快速回复。
    • @JmanxC 那是无效的操作数组合。没有办法用两个内存地址对指令进行编码。此站点显示有效组合:http://pdos.csail.mit.edu/6.828/2010/readings/i386/MOV.htm
    【解决方案2】:

    这里的问题是,numbernumber2 不是 数字,即直接文字。相反,它们被解释为绝对内存地址和相应的指令,如果它们存在的话,例如

     mov eax, [0x80000100]        ;; vs
     mov [0x80000104], [eax]     ;; Invalid instruction
    

    还必须注意指令格式,正如 Mika Lammi 所回答的那样——是指令

     mov src, dst   ;; vs
     mov dst, src
    

    此外,寄存器大小应与变量大小相匹配;即

    .data
    number   db 1;   // this is a byte
    .code
    mov al, number
    

    【讨论】:

    • 谢谢你。关于可变大小和寄存器大小,我对数据如何存储在 AH 和 AL 寄存器中有点困惑。如果我将数字 53 存储在假设 ax 中,那么它将存储在低位字节(即:xxxxxxxx 53 和 al)还是高位字节(即:53 xxxxxxxx 和 ah)中,我的印象是高位意味着二进制数的前 8 位和低位将是后 8 位,但是我遇到过论坛帖子对这些寄存器的说法相反,所以我有点困惑
    • P.S 也许数据以小端格式存储,这就是我的逻辑关闭的原因?感谢您的快速回复!
    • 在 IA 中,如果 AX 包含整数 53,则 AH=0 且 AL=53。通常,必须将变量存储在number dw 53 而不是db 53dw 是字,db 是字节。无法从字节大小的变量中读取字,通过movzx eax, byte ptr [eax](用零填充 eax 的前 24 位)或 movsx(复制符号位)可以从字节中读取 32 位字AL 到 eax 的前 24 位。