Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 使用GAS从标签加载单个字节到arm64中的寄存器_Assembly_Arm64_Gnu Assembler - Fatal编程技术网

Assembly 使用GAS从标签加载单个字节到arm64中的寄存器

Assembly 使用GAS从标签加载单个字节到arm64中的寄存器,assembly,arm64,gnu-assembler,Assembly,Arm64,Gnu Assembler,我想使用ldrb指令将单个字节从内存加载到寄存器中。但是,如果第二个操作数是一个标签,这似乎是不可能的。完整的最小可重复性注释示例: // GNU Assembly, aarch64 Linux .data .equ SYS_EXIT, 93 .equ SUCCESS, 0 CHAR: .byte 1 .text .global _start _start: // none of these work, but why? // ldrb w19, CHAR

我想使用
ldrb
指令将单个字节从内存加载到寄存器中。但是,如果第二个操作数是一个标签,这似乎是不可能的。完整的最小可重复性注释示例:

// GNU Assembly, aarch64 Linux

.data

.equ SYS_EXIT, 93
.equ SUCCESS, 0

CHAR:
    .byte 1

.text

.global _start

_start:
    // none of these work, but why?
    // ldrb w19, CHAR       // invalid addressing mode at operand 2
    // ldrb w19, =CHAR      // invalid addressing mode at operand 2
    // ldrb w19, [CHAR]     // 64-bit integer or SP register expected at operand 2
    // ldr w19, CHAR        // loads 4 bytes instead of 1 byte

    // I have to do this but it's verbose and clunky
    ldr x20, =CHAR
    ldrb w19, [x20]
    // is there any way to coalesce the above 2 instructions into 1?

    mov x8, SYS_EXIT
    mov x0, SUCCESS
    svc 0
理想情况下,我希望编写
ldrb,
,例如
ldrbw19,CHAR
,并让它像我预期的那样从
CHAR
的内存地址加载一个字节,而不是抛出汇编程序错误

这些都不管用,但为什么

因为采用PC相对文字的加载指令只有
ldr
ldrsw


如Siguza所说,CPU根本没有任何此类指令,请参见中的表C3-16。
LDRB
支持的唯一寻址模式是寄存器基址+寄存器或立即偏移,如您在《体系结构参考手册》(任何汇编程序员的必读)中所见。汇编程序拒绝汇编不存在的指令是完全正确的

因此,你不能在一个单一的指令中实现你想要的;你需要两个。然而,这两条指令可能比您选择的更有效。标准的习语似乎是:

adrp x19, CHAR
ldrb w19, [x19, #:lo12:CHAR]
这里,
adrp
将加载
x19
,地址的前52位为
CHAR
;指令编码
CHAR
所在页面相对于当前指令页面的偏移量(该偏移量由链接器或加载器计算和填充),以便生成位置无关的代码。然后在寻址模式下通过偏移量添加地址的低12位(限制为12位);此偏移量在链接时已知,因为加载时重新定位仅以页面或更多页面为单位。请注意,我们可以使用与加载目标相同的寄存器进行地址计算;我们不需要第二个

与您的方法相比,这避免了使用文字池的需要,节省了内存的额外负载和池中8字节的空间


如果你仍然觉得它太“冗长”,你可以将它包装在宏中。

这不是汇编程序的错误,显然
LDRB
没有PC相对偏移量。