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