【问题标题】:STR (ARM gnu Assembly)cannot change memory inSTR(ARM gnu 程序集)无法更改内存
【发布时间】:2022-01-12 06:39:04
【问题描述】:

我想通过 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 部分是只读的。我怎样才能将其设置为可写?

【问题讨论】:

  • 您的入口点在哪里?如果是start,那么为什么它在你的数据部分,为什么没有从那里到你的循环的分支?
  • @Michael 我只是删除数据部分(不需要)。它是一样的。
  • 在调试器中单步执行代码时会看到什么?如果start: 现在位于.text 部分中的代码之后,那么它仍然不会执行。
  • 你确定你的模拟机器实际上在地址 0x4000 有 RAM 吗?你能用 QEMU 监视器检查吗?
  • 你没有说你的 QEMU 命令行是什么,或者你正在使用什么 QEMU 版本。我同意迈克尔的观点,可能的原因是 0x4000 要么什么都没有,要么是 ROM/flash。您需要设置链接器映射以匹配您正在运行的任何(模拟)硬件。

标签: arm gdb qemu gnu-assembler gnu-arm


【解决方案1】:

正如本页所述: [http://www.bravegnu.org/gnu-eprog/using-ram.html][1]

连接板有一个 64 MB 的 RAM,从地址 0xA0000000 开始,在 可以存储哪些变量。

所以我将 ram_address 更改为 0xA0000000 并且它起作用了,通过 x/4xw 0xA0000000 我可以看到 RAM 中的变化。

【讨论】:

    【解决方案2】:

    这是因为 Connex 机器在地址 0 处没有 RAM,它有 ROM(严格来说,它是一个 cfi01 闪存设备)。所以你可以在那里加载你的二进制文件,你可以从那里执行并读取数据,但试图在那里写入数据是行不通的。这与在这种类型的真实硬件上相同。 (您还可以看到您正在将二进制文件加载到闪存中,因为您使用 QEMU 的“-pflash”选项来加载它。)

    Connex 板上的 RAM 从地址 0xa0000000 开始。您需要使用至少将数据和 bss 部分正确放入 RAM 的链接器映射。如果您愿意,您可以将包括代码在内的整个二进制文件放入 RAM:这可能是让某些东西正常工作的最简单的方法。请注意,如果您想要闪存中的代码和 RAM 中的数据,那么您需要做一些比通过 -pflash 加载单个二进制 blob 更复杂的事情。此处的选项包括“通过通用加载器设备加载 ELF 文件”(然后将 ELF 文件的不同段放入内存映射中的正确位置,即使它们不连续)或“将 blob 加载到闪存中能够在启动时将自己的数据重新定位(复制)到 RAM 中”。

    您还需要确保代码的堆栈位于 RAM 中。不小心将堆栈指针设置为指向 ROM 可能会产生一些奇怪的故障模式,其中代码似乎执行得很好,直到某些东西(通常是函数返回)需要再次从堆栈中读回一些东西......

    附带说明,除非您特别想运行旧的 PXA255 代码,否则 Connex 是一个有点奇怪的板选择。

    【讨论】:

    猜你喜欢
    • 2012-10-13
    • 2019-08-25
    • 1970-01-01
    • 2012-12-06
    • 1970-01-01
    • 1970-01-01
    • 2016-10-25
    • 1970-01-01
    • 2021-11-21
    相关资源
    最近更新 更多