Assembly 在arm ONE eabi gdb模拟器中,来自程序入口点的ldr似乎给出了无意义的结果
我正在学习为裸金属覆盆子pi编写ARM汇编程序。Assembly 在arm ONE eabi gdb模拟器中,来自程序入口点的ldr似乎给出了无意义的结果,assembly,arm,gdb,Assembly,Arm,Gdb,我正在学习为裸金属覆盆子pi编写ARM汇编程序。 我在x86机器上运行arm none eabi gdb进行调试。 arm none eabi gdb附带的模拟器在以下简单程序中的行为与我预期的不同: .section ".text.startup" .global _start _start: nop nop nop ldr r0, =_start ldr r2, [r0] ldr r3, [r0, #4] l
我在x86机器上运行arm none eabi gdb进行调试。
arm none eabi gdb
附带的模拟器在以下简单程序中的行为与我预期的不同:
.section ".text.startup"
.global _start
_start:
nop
nop
nop
ldr r0, =_start
ldr r2, [r0]
ldr r3, [r0, #4]
ldr r4, [r0, #8]
我希望nop
的代码加载到寄存器r2
、r3
和r4
。然而,当我编译程序时
$ arm-none-eabi-gcc -mfloat-abi=hard -nostartfiles -mfpu=neon-vfpv4 -march=armv7-a -mtune=cortex-a7 -O0 test.S -o kernel.elf
得到
$ arm-none-eabi-objdump -S kernel.elf
kernel.elf: file format elf32-littlearm
Disassembly of section .text:
00004000 <_start>:
4000: e320f000 nop {0}
4004: e320f000 nop {0}
4008: e320f000 nop {0}
400c: e59f0008 ldr r0, [pc, #8] ; 401c <_start+0x1c>
4010: e5902000 ldr r2, [r0]
4014: e5903004 ldr r3, [r0, #4]
4018: e5904008 ldr r4, [r0, #8]
401c: 00004000 .word 0x00004000
$arm none eabi objdump-S kernel.elf
kernel.elf:文件格式elf32 littlearm
第节的分解。正文:
00004000 :
4000:e320f000 nop{0}
4004:e320f000 nop{0}
4008:e320f000 nop{0}
400c:e59f0008 ldr r0,[pc,#8];401c
4010:e5902000 ldr r2[r0]
4014:e5903004 ldr r3[r0,#4]
4018:e5904008 ldr r4[r0,#8]
401c:00004000.字0x00004000
并在模拟机内的arm none eabi gdb
中运行,寄存器r3
和r4
加载了0xe320f000
,这是正确的。但是,
r2
加载了0xe7ffdefe
,它似乎不在任何地方
我有arm-none-eabi-gdb
7.8.1版和arm-none-eabi-gcc
4.8.3版。这是模拟器中的错误还是我遗漏了一些明显的东西
另外,我尝试将入口点更改为
0x4000
,而不是链接脚本中的默认0x8000
。问题仍然存在,因此模拟器无法从入口点内存地址正确加载?是否在\u start:
处设置了断点0xe7ffdefe
可能是软件断点的机器指令,GDB用它重写了第一个nop
,以实现断点
您可以使用\u start:mov edi,[rel\u start]
在x86上复制此命令,RDI的低字节将是0xcc
(int3
)或0x8b
(mov r32,r/m32
)取决于您是否在\u start
设置了断点
GDB不会试图伪造代码来阻止它看到软件断点。您可以让GDB使用硬件断点来解决这个问题。使用
hbreak
而不是break
()
但是GDB确实在x/i
或disas
GDB命令中隐藏了这一点,呈现出未修改代码字节的幻觉
顺便说一句,您可以使用
starti
运行程序,但在第一条指令执行之前停止。(即,在入口点设置一个临时断点,其优点是即使入口点没有标签也可以工作。)
然后您可以执行一个步骤(也不涉及设置软件断点),代码将按预期执行。谢谢!这很有道理。我确实在
\u start
设置了一个断点,然后像傻瓜一样反复检查x/x 0x8000
。顺便说一句,我检查了starti
在我的arm-none-eabi-gdb
7.8.1版中不可用,但在8.2.1版中可用。