代码之家  ›  专栏  ›  技术社区  ›  pretzelhammer Paras Bhattrai

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

  •  2
  • pretzelhammer Paras Bhattrai  · 技术社区  · 5 年前

    我想使用 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 <reg>, <label> ,例如。 ldrb w19, CHAR ,并让它从 CHAR 的内存地址,而不是抛出汇编程序错误。

    0 回复  |  直到 5 年前
        1
  •  4
  •   Nate Eldredge    5 年前

    正如Siguza所说,CPU根本没有任何这样的指令。支持的唯一寻址模式 LDRB

    used by compilers 似乎是:

    adrp x19, CHAR
    ldrb w19, [x19, #:lo12:CHAR]
    

    adrp 将加载 x19 CHAR ; 该指令对其上的页面偏移量进行编码 烧焦

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

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

        2
  •  1
  •   Siguza    5 年前

    这些都不管用,但为什么?

    ldr ldrsw

    screenshot of table C3-16

    见表C3-16 ARMv8 Reference Manual .

    推荐文章