STR(ARM gnu 程序集)无法更改内存
STR (ARM gnu Assembly)cannot change memory in
我想通过STR指令改变内存中的一些位。
.text
.equ ram_address,0x4000
.equ pattern,0x55
.equ counter,50
mov r0,#pattern
mov r1,#counter
mov r2,#ram_address
back: str r0,[r2]
add r2,#4
subs r1,r1,#1
bne back
here: b here
.data
i: .word 0xffffffff
并使用这样的 makefile:
TOOLCHAIN=arm-none-eabi
Assembler=${TOOLCHAIN}-as
Linker=${TOOLCHAIN}-ld
Objcpy=${TOOLCHAIN}-objcopy
Compile_Options= -g
Link_Options=-Ttext=0x0 -Tbss=0x4000 # -Tdata=0x4000 #
.PHONY : clean
.PRECIOUS : %.bin %.elf %.o
all : create
create : flash.bin
flash.bin:main.bin
dd if=/dev/zero of=flash.bin bs=4096 count=4096
dd if=main.bin of=flash.bin bs=4096 conv=notrunc
%.bin:%.elf
$(Objcpy) -O binary $< $@
%.elf:%.o
$(Linker) $(Link_Options) -o $@ $<
%.o:%.S
$(Assembler) $(Compile_Options) $< -o $@
clean :
rm -f *.o *.bin *.elf
这是 qemu 命令:
qemu-system-arm -S -M connex -pflash flash.bin -nographic -serial /dev/null
QEMU 模拟器版本 6.1.0
我通过 qemu-arm-system 和 gdbserver 以及 x/16xw 0x4000
命令检查内存。结果是:
0xffffffff 0x00000000 0x00000000 0x00000000
这意味着.data 部分是只读的。我怎样才能将其设置为可写?
发生这种情况是因为 Connex 机器在地址零处没有 RAM,它有 ROM(严格来说,它是一个 cfi01 闪存设备)。所以你可以在那里加载你的二进制文件,你可以从那里执行,并读取数据,但是试图在那里写入数据是行不通的。这与在这种类型的真实硬件上的情况相同。 (您还可以看到您正在将二进制文件加载到闪存中,因为您正在使用 QEMU 的“-pflash”选项来加载它。)
Connex 板上的 RAM 从地址 0xa0000000 开始。您需要使用至少将数据和 bss 部分正确放入 RAM 的链接器映射。如果愿意,您可以将包括代码在内的整个二进制文件放入 RAM:这可能是让某些东西正常工作的最简单方法。请注意,如果您想要闪存中的代码和 RAM 中的数据,那么您需要做一些比通过 -pflash 加载单个二进制 blob 更复杂的事情。这里的选项包括“通过通用加载器设备加载 ELF 文件”(然后将 ELF 文件的不同段放入内存映射中的正确位置,即使它们不连续)或“将 blob 加载到闪存中能够在启动时将自己的数据重新定位(复制)到 RAM 中。
您还需要确保您的代码堆栈位于 RAM 中。不小心将堆栈指针设置为指向 ROM 会产生一些奇怪的故障模式,其中代码似乎可以正常执行,直到某些东西(通常是函数-return)需要再次从堆栈中读取某些东西...
作为旁注,Connex 是一个有点奇怪的板选择,除非你特别想要 运行 旧的 PXA255 代码。
如本页所述:
[http://www.bravegnu.org/gnu-eprog/using-ram.html][1]
The connex board has a 64 MB of RAM starting at address 0xA0000000, in
which variables can be stored.
所以我将 ram_address 更改为 0xA0000000 并且它起作用了,通过 x/4xw 0xA0000000
我可以看到 RAM 中的变化。
我想通过STR指令改变内存中的一些位。
.text
.equ ram_address,0x4000
.equ pattern,0x55
.equ counter,50
mov r0,#pattern
mov r1,#counter
mov r2,#ram_address
back: str r0,[r2]
add r2,#4
subs r1,r1,#1
bne back
here: b here
.data
i: .word 0xffffffff
并使用这样的 makefile:
TOOLCHAIN=arm-none-eabi
Assembler=${TOOLCHAIN}-as
Linker=${TOOLCHAIN}-ld
Objcpy=${TOOLCHAIN}-objcopy
Compile_Options= -g
Link_Options=-Ttext=0x0 -Tbss=0x4000 # -Tdata=0x4000 #
.PHONY : clean
.PRECIOUS : %.bin %.elf %.o
all : create
create : flash.bin
flash.bin:main.bin
dd if=/dev/zero of=flash.bin bs=4096 count=4096
dd if=main.bin of=flash.bin bs=4096 conv=notrunc
%.bin:%.elf
$(Objcpy) -O binary $< $@
%.elf:%.o
$(Linker) $(Link_Options) -o $@ $<
%.o:%.S
$(Assembler) $(Compile_Options) $< -o $@
clean :
rm -f *.o *.bin *.elf
这是 qemu 命令:
qemu-system-arm -S -M connex -pflash flash.bin -nographic -serial /dev/null
QEMU 模拟器版本 6.1.0
我通过 qemu-arm-system 和 gdbserver 以及 x/16xw 0x4000
命令检查内存。结果是:
0xffffffff 0x00000000 0x00000000 0x00000000
这意味着.data 部分是只读的。我怎样才能将其设置为可写?
发生这种情况是因为 Connex 机器在地址零处没有 RAM,它有 ROM(严格来说,它是一个 cfi01 闪存设备)。所以你可以在那里加载你的二进制文件,你可以从那里执行,并读取数据,但是试图在那里写入数据是行不通的。这与在这种类型的真实硬件上的情况相同。 (您还可以看到您正在将二进制文件加载到闪存中,因为您正在使用 QEMU 的“-pflash”选项来加载它。)
Connex 板上的 RAM 从地址 0xa0000000 开始。您需要使用至少将数据和 bss 部分正确放入 RAM 的链接器映射。如果愿意,您可以将包括代码在内的整个二进制文件放入 RAM:这可能是让某些东西正常工作的最简单方法。请注意,如果您想要闪存中的代码和 RAM 中的数据,那么您需要做一些比通过 -pflash 加载单个二进制 blob 更复杂的事情。这里的选项包括“通过通用加载器设备加载 ELF 文件”(然后将 ELF 文件的不同段放入内存映射中的正确位置,即使它们不连续)或“将 blob 加载到闪存中能够在启动时将自己的数据重新定位(复制)到 RAM 中。
您还需要确保您的代码堆栈位于 RAM 中。不小心将堆栈指针设置为指向 ROM 会产生一些奇怪的故障模式,其中代码似乎可以正常执行,直到某些东西(通常是函数-return)需要再次从堆栈中读取某些东西...
作为旁注,Connex 是一个有点奇怪的板选择,除非你特别想要 运行 旧的 PXA255 代码。
如本页所述: [http://www.bravegnu.org/gnu-eprog/using-ram.html][1]
The connex board has a 64 MB of RAM starting at address 0xA0000000, in which variables can be stored.
所以我将 ram_address 更改为 0xA0000000 并且它起作用了,通过 x/4xw 0xA0000000
我可以看到 RAM 中的变化。