Gcc str和ldr指令不使用相同的地址

Gcc str和ldr指令不使用相同的地址,gcc,assembly,arm,mmu,Gcc,Assembly,Arm,Mmu,我有一个奇怪的问题,MMU将内存转换为str而不是ldr指令。我正在为arm7TDMI使用gcc(无优化)进行编译 程序输入一个函数并在堆栈中存储4个参数(r0到r3) 我有这些记录: r0 = 0x1e10c8 r1 = 0x12adf0 r2 = 0x0 r3 = 0x2 r11 = 0x12ade4 MMU处于活动状态,0x0和0x00FFFFFF之间的所有内容在物理上位于0xC0000000和0xC0FFFF之间 pc执行这4行装配: str r0, [r11, #-24] str r

我有一个奇怪的问题,MMU将内存转换为str而不是ldr指令。我正在为arm7TDMI使用gcc(无优化)进行编译

程序输入一个函数并在堆栈中存储4个参数(r0到r3) 我有这些记录:

r0 = 0x1e10c8
r1 = 0x12adf0
r2 = 0x0
r3 = 0x2
r11 = 0x12ade4
MMU处于活动状态,0x0和0x00FFFFFF之间的所有内容在物理上位于0xC0000000和0xC0FFFF之间

pc执行这4行装配:

str r0, [r11, #-24]
str r1, [r11, #-28]
str r2, [r11, #-32]
strb r3, [r11, #-33]
这是执行后存储数据的内存范围:

0xC012ADC0  02000000  ....
0xC012ADC4  00000000  ....
0xC012ADC8  0012ADF0  ð­..
0xC012ADCC  001E10C8  È...
这个内存范围是FF

0x0012ADC0  FFFFFFFF  ÿÿÿÿ
0x0012ADC4  FFFFFFFF  ÿÿÿÿ
0x0012ADC8  FFFFFFFF  ÿÿÿÿ
0x0012ADCC  FFFFFFFF  ÿÿÿÿ
我们看到,由于MMU,数据被物理存储在0xC0000000区域中

由于我处于调试模式,因此可以使用以下值手动更改此区域:

0x0012ADC0  F4F4F4F4  ôôôô
0x0012ADC4  3F3F3F3F  ????
0x0012ADC8  F2F2F2F2  òòòò
0x0012ADCC  1F1F1F1F  ....
现在执行2-3次装配之后,我有一条装配线:

ldr r3, [r11, #-24]
我执行这一行,在r3中有一个值:

r3=0x1f1f1f1f
(如果我不在0x0012ADC0和0x0012ADCC之间更改内存,我通常会得到0xFFFFFF…)

我真的不明白为什么r3不等于0x1E10C8。这就像执行str命令时MMU执行其工作一样,但当执行ldr时,MMU不会转换地址(0x0012ADCC而不是0xC012ADCC)。有件事我不能理解

为了以防万一,这里有一个有关装配说明的快照:

      kapiReceiveQueue:
000195fc:   push {r11, lr}
00019600:   add r11, sp, #4
00019604:   sub sp, sp, #32
00019608:   str r0, [r11, #-24]         <----- r0 stored physically at C012ADCC
0001960c:   str r1, [r11, #-28]
00019610:   str r2, [r11, #-32]
00019614:   strb r3, [r11, #-33]    ; 0x21
 693          switch (Option)
00019618:   ldrb r3, [r11, #-33]    ; 0x21
0001961c:   cmp r3, #2
00019620:   beq 0x1974c <kapiReceiveQueue+336>
...
0001974c:   ldr r3, [r11, #-24]         <------ r3 get the value of physical address 0x12ADCC
00019750:   ldr r2, [r3]
00019754:   sub r3, r11, #17
00019758:   mov r0, r2

任何帮助都将不胜感激

如何在“调试模式”下检查和更改内存?如果这是一个ARM7TDMI,那么物理映射和虚拟映射之间甚至两个虚拟映射之间都没有内存一致性,而且如果您查看或更改原始物理内容,它不会反映在缓存中。这将导致奇怪的MMU行为(虽然不是MMU的错,而是缓存问题)。硬件是如何物理映射的?地址是完全解码的还是有别名?您的硬件是否经过良好测试?您如何在“调试模式”下检查和更改内存?如果这是一个ARM7TDMI,那么物理映射和虚拟映射之间甚至两个虚拟映射之间都没有内存一致性,而且如果您查看或更改原始物理内容,它不会反映在缓存中。这将导致奇怪的MMU行为(虽然不是MMU的错,而是缓存问题)。硬件是如何物理映射的?地址是完全解码的还是有别名?你的硬件经过测试了吗?
arm-none-eabi-gcc  -march=armv4t -mcpu=arm7tdmi -dp  -DNG_COMP_GCC -c
-Wa,-adhlns="../../Base/Lib/Pa/Kapi.o.lst" -fmessage-length=0 -fno-zero-initialized-
in-bss -MMD -MP -MF"../../Base/Lib/Pa/Kapi.d" -MT"../../Base/Lib/Pa/Kapi.d" -fpic
-mlittle-endian -Wall -DNGHW_TOPMEM_ADDR=0x00800000 -DNG_CPU_ARM -DNG_CPU_ARMv4T 
-DNG_CODE_ARM -DNG_LITTLE_ENDIAN -DNG_DEBUG -DNG_RTOS -DNG_COMP_GCC -DNG_RTOS_UCOSII 
-DDHCP_CLIENT -g3 -gdwarf-2  ../../Base/Kernel/Alos/Ucos-II/Kapi.c -o"../../Base/Lib/Pa/Kapi.o"