NASM 分配一个填充寄存器值的数组

NASM Allocate an Array Filled with Values from Registers

提问人:Robbie 提问时间:11/13/2023 更新时间:11/13/2023 访问量:31

问:

我正在编写一个简单的 NASM 汇编程序,当给定与该寄存器对应的数字 ( thru ) 时,它将获得 16 个 64 位寄存器之一的值 ( thru )。我的方法是分配一个包含 16 个寄存器值的数组,然后在索引处读取数组。我的代码如下:raxr15longi015i

SECTION .data
    ; array containing all our registers
    regs    dq rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp, r8, r9, r10, r11, r12, r13, r14, r15

SECTION .text

global getReg

getReg:
    ; rdi is the first argument we got, and the registers are 8 bytes each,
    ;  so the desired index is our argument multiplied by 8
    imul   rax, rdi, 8
    ; move the quadword at index rax of regs array into register rax (for returning)
    mov    rax, [regs + rax]
    ret

但是,当我尝试将上述内容与 组装在一起时,我在第 3 行得到了 16 次(每个寄存器一次)。我是组装新手,几乎不知所措(努力理解错误甚至意味着什么以及它的症状是什么)。希望得到一些帮助,并可能得到一些关于我文件中其他错误的相关提示或一般 NASM 最佳实践。谢谢!nasm -f elf64 getReg.s -o getReg.oexpression is not simple or relocatable

汇编 64 位 NASM CPU 寄存器

评论

1赞 500 - Internal Server Error 11/13/2023
这条线到底是什么意思?regs...
0赞 Peter Cordes 11/13/2023
的操作数必须是链接时间常量,如整数或符号地址。寄存器内容仅在运行时存在。无法设置镜像 x86 或大多数其他 ISA 上的寄存器值的内存区域。一些 ISA(如 AVR)的寄存器在特定地址进行内存映射,因此即使如此,您也无法设置自定义映射。请记住,汇编语言是一种非常低级的语言;每行只能向当前部分发出字节,也可以不向当前部分发出字节。运行时发生的任何事情都必须由 CPU 执行的机器代码触发。dq
1赞 Peter Cordes 11/13/2023
另请注意,您的寄存器编号混淆了。x86 机器代码中的前 4 个寄存器编号是 RAX、RCX、RDX、RBX。(为什么前四个 x86 通用寄存器的命名顺序如此不直观?)
2赞 Peter Cordes 11/13/2023
如果要在运行时索引寄存器的当前值,则需要将它们全部存储到数组中(带有 16 或指令),或者需要比较和分支或间接跳转到指令块,例如 / ,只有特殊情况不需要任何指令即可将值获取到 RAX 中,即它的跳转目标可以只是“完成”地址。movpushmov rax, r13jmp donei=0
2赞 ecm 11/13/2023
也可以使用 SMC(自修改代码)将 16 个寄存器中的一个编码为一条指令,该指令将所需的寄存器作为源。但是,创建调度表(如 C )并跳转到对相应寄存器进行硬编码的一小段代码是更简单、更好的做法。就像@PeterCordes建议的那样。switch

答: 暂无答案