在汇编 ARMv8 中符号扩展后逻辑左移丢失位

logical shift left losing bits after sign extend in assembly ARMv8

我正在使用符号扩展将 32 位变量更改为 64 位变量。但是,当我在 64 位变量上使用逻辑左移时,它会丢失一些位,就好像它仍然是 32 位一样。

我希望最终能够将所有内容从我的原始变量转移到 64 位变量的上端。 (0xFFFFFFFF00000000 是我期待的结果)

下面的代码显示了 8 位的移位,以说明丢失位的位置:

str_fmt:.string "\nWord Value: 0x%08x \nWord Extended to 64-bit: 0x%016x\nLSL: 0x%016x\n\n"

        .balign 4   
        .global main    

main:   stp     x29, x30, [sp, -16]!    
        mov     x29, sp         

        mov     w19, 0xFFFFFFFF
        sxtw    x20, w19

        lsl     x21, x20, 8

results:
        adrp    x0, str_fmt     
        add     x0, x0, :lo12:str_fmt
        mov     w1, w19             
        mov     x2, x20
        mov     x3, x21
        bl      printf

done:   ldp     x29, x30, [sp], 16  
        ret 

输出结果如下:

字值:0xffffffff 字扩展为 64 位:0x00000000ffffffff LSL:0x00000000ffffff00

我的代码中缺少什么允许逻辑左移导致 0xFFFFFFFF00000000?

x 格式说明符打印一个 unsigned 参数,这是我知道的 ARM ABI 上的 32 位类型。这导致 printf 忽略参数的高 32 位。使用 llx 打印一个 long long unsigned 参数; long long unsigned 至少是 64 位类型。