Assembly 如何从.data节正确加载整数值

Assembly 如何从.data节正确加载整数值,assembly,arm,Assembly,Arm,从逻辑上讲,我的代码是功能性的。但是,只有当我在主函数中将寄存器x1手动设置为一个值(例如4)时,它才起作用。如果我尝试使用ldr x1,=targ,并尝试通过打印出来测试该值,则得到-2147196624。有人能帮我了解发生了什么事吗 .text .global main .extern printf main: ldr x1,=targ // set x1 to n mov x3,#0 // set x3 and x4 mov x4,#1

从逻辑上讲,我的代码是功能性的。但是,只有当我在主函数中将寄存器x1手动设置为一个值(例如4)时,它才起作用。如果我尝试使用ldr x1,=targ,并尝试通过打印出来测试该值,则得到-2147196624。有人能帮我了解发生了什么事吗

   .text
  .global main
  .extern printf
main:
    ldr x1,=targ  // set x1 to n
    mov x3,#0   // set x3 and x4
    mov x4,#1
    mov x5,#1   // set x5 (count = 1)
    bl fibo
    b done

fibo:
    mov x9, x3
    mov x3, x4
    add x4, x9, x4
    add x5, x5, #1
    cmp x5, x1
    ble fibo
    br x30

done:
    mov x1, x3
    ldr x0,=string
    bl printf

.data
    string:
        .asciz "%d\n"
    targ:
        .byte 4
.end
输出

上面的代码没有打印任何内容,它被困在fibo分支中的无限循环中,因为
blefibo
条件始终满足

ldr x1,=targ
是指targ的“地址”,而不是targ的值。该指令需要一种寻址模式,这种寻址模式可以达到很远的距离,因此它使用pc相对寻址

你自己试试吧

.text 

    ldr x1,=targ
    nop
    nop
    
.data

targ:
    .byte 4

aarch64-none-elf-as so.s -o so.o
aarch64-none-elf-ld -Ttext=0x1000 -Tdata=0x2000 so.o -o so.elf
aarch64-none-elf-objdump -d so.elf


0000000000001000 <.text>:
    1000:   58000081    ldr x1, 1010 <__data_start-0xff0>
    1004:   d503201f    nop
    1008:   d503201f    nop
    100c:   00000000    
    1010:   00002000    .word   0x00002000
    1014:   00000000    .word   0x00000000
.text
ldr x1,=targ
不
不
.数据
目标:
.字节4
aarch64无elf as so.s-o so.o
AARC64非elf ld-Ttext=0x1000-Tdata=0x2000 so.o-o so.elf
AARC64非elf对象转储-d so.elf
0000000000001000 :
1000:58000081 ldr x1,1010
1004:d503201f nop
1008:d503201f nop
100c:00000000
1010:000020000.字0x000020000
1014:00000000。单词0x00000000
它正在加载标签的地址

aarch64-none-elf-objdump -D so.elf

so.elf:     file format elf64-littleaarch64


Disassembly of section .text:

0000000000001000 <.text>:
    1000:   58000081    ldr x1, 1010 <__data_start-0xff0>
    1004:   d503201f    nop
    1008:   d503201f    nop
    100c:   00000000
    1010:   00002000
    1014:   00000000

Disassembly of section .data:

0000000000002000 <__data_start>:
    2000:   
aarch64无elf objdump-D so.elf
so.elf:文件格式elf64-LittleArch64
第节的分解。正文:
0000000000001000 :
1000:58000081 ldr x1,1010
1004:d503201f nop
1008:d503201f nop
100c:00000000
1010:   00002000
1014:   00000000
分解截面。数据:
0000000000002000 :
2000:   
所以

.text
ldr x1,=targ
ldr-x1[x1]
不
不
不
.数据
目标:
.字节4
第节的分解。正文:
0000000000001000 :
1000:580000c1 ldr x1,1018
1004:f9400021 ldr x1[x1]
1008:d503201f nop
100c:d503201f无
1010:d503201f nop
1014:   00000000    
1018:000020000.字0x000020000
101c:00000000。字0x00000000
但也有一个问题,ldr不是一个字节加载操作

我的64位手臂有点生锈了

.text 

    ldr x1,=targ
    ldrb w1,[x1]
    nop
    nop
    nop
    
.data

targ:
    .byte 4

0000000000001000 <.text>:
    1000:   580000c1    ldr x1, 1018 <__data_start-0xfe8>
    1004:   39400021    ldrb    w1, [x1]
    1008:   d503201f    nop
    100c:   d503201f    nop
    1010:   d503201f    nop
    1014:   00000000    
    1018:   00002000    .word   0x00002000
    101c:   00000000    .word   0x00000000
.text
ldr x1,=targ
ldrb w1[x1]
不
不
不
.数据
目标:
.字节4
0000000000001000 :
1000:580000c1 ldr x1,1018
1004:39400021 ldrb w1[x1]
1008:d503201f nop
100c:d503201f无
1010:d503201f nop
1014:   00000000    
1018:000020000.字0x000020000
101c:00000000。字0x00000000
您可以在arm文档中查找这一点(如果没有适当的文档,就没有理由使用汇编语言。armv8-a的arm体系结构参考手册)

580000c1 ldr x1,1018
01011000000000....
LDR(文字)以0x011000开头,因此这就是该指令。(这里的0x表示x不是0或1,不是十六进制数,0n011000)

0c1
000011000001
00001110 00001 immed 0x6寄存器x1
64位变量
当opc==01时适用。(opc是位31:30)
LDR,
0x1018-0x1000-0x18 00011000
110 00
4*6=24=0x18,0x1000+0x18=0x1018。

因此,偏移量是相对的,正如人们所期望的那样,所以这一切都是有意义的。

“从逻辑上讲,我的代码是功能性的。”在多个逻辑错误和问题的背景下,这意味着什么?为什么你没有修复前面问题中指出的错误?@ErikEidt嗯,我在我的机器上修复了它,但我没有在我的帖子中反映这一变化,但我现在更新了它。我相信这只是一个打印问题,我通过暗示用
mov-x1、=targ
行简单替换
ldr-x1、=targ
行,4打印所需的输出来限定我的声明。@ErikEidt您对我当前的问题有什么贡献吗?为什么标记这个x86?
.text 

    ldr x1,=targ
    ldrb w1,[x1]
    nop
    nop
    nop
    
.data

targ:
    .byte 4

0000000000001000 <.text>:
    1000:   580000c1    ldr x1, 1018 <__data_start-0xfe8>
    1004:   39400021    ldrb    w1, [x1]
    1008:   d503201f    nop
    100c:   d503201f    nop
    1010:   d503201f    nop
    1014:   00000000    
    1018:   00002000    .word   0x00002000
    101c:   00000000    .word   0x00000000
580000c1    ldr x1, 1018 <__data_start-0xfe8>

01011000000000....
0c1
000011000001
0000110 00001 immed 0x6 register x1

64-bit variant 
Applies when opc == 01 . (opc is bits 31:30)
LDR <Xt>, <label>

0x1018 - 0x1000 -0x18  00011000
110 00

4*6 = 24 = 0x18, 0x1000+0x18 = 0x1018.