Valvano的书中有一段Keil汇编代码(3.3.3内存访问指令(:
; Keil Syntax
LDR R5, PAaddr
MOV R6, #0x55
STR R6, [R5]
;outside of execution
PAaddr DCD 0x400043FC
第一行LDR R5, PAaddr
由汇编程序翻译为
LDR R5, [PC, #16]
其中CCD_ 2表示CCD_ 3和CCD_。
我不明白#16
是怎么来的。根据Keil的ARM和Thumb指令,MOV
是一条16位指令(因此是2字节(。我找不到STR
或DCD
的指令大小,但从ARM的指令集摘要来看,STR
的周期是MOV
的两倍,所以我直观地猜测STR
的指令大小是MOV
的两倍(或4字节(。DCD
只是将值存储到ROM中,所以它不能比MOV大。如果我用字节来总结指令大小(MOV为2,STR为4,DCD可能为1或2(,那么从第二条到最后一条指令之间应该有7或8个字节,或者从PC跳转#7或#8。
我手头没有Kiel,但这并不重要,你没有提供足够的信息(你的目标体系结构/核心是什么(,arm并没有很好地记录所有这些。
所以通用拇指
.thumb
LDR R5, PAaddr
MOV R6, #0x55
STR R6, [R5]
.align
PAaddr: .word 0x400043FC
Disassembly of section .text:
00000000 <PAaddr-0x8>:
0: 4d01 ldr r5, [pc, #4] ; (8 <PAaddr>)
2: 2655 movs r6, #85 ; 0x55
4: 602e str r6, [r5, #0]
6: 46c0 nop ; (mov r8, r8)
00000008 <PAaddr>:
8: 400043fc .word 0x400043fc
立即偏移量添加到指令的Align(PC,4(值以形成地址。对于编码T1,允许的值是0-1020范围内的四的倍数。
因此ALIGN(0x00+2,4(=0x04。0x08-4=4=一个单词。所以1个字0x4D01,01就是立即数。
.thumb
nop
LDR R5, PAaddr
MOV R6, #0x55
STR R6, [R5]
.align
PAaddr: .word 0x400043FC
00000000 <PAaddr-0x8>:
0: 46c0 nop ; (mov r8, r8)
2: 4d01 ldr r5, [pc, #4] ; (8 <PAaddr>)
4: 2655 movs r6, #85 ; 0x55
6: 602e str r6, [r5, #0]
00000008 <PAaddr>:
8: 400043fc .word 0x400043fc
ALIGN(0x02+2,4(=0x4。0x08-0x04=0x04,一个字0x4D01编码。
.cpu cortex-m3
.thumb
LDR R5, PAaddr
MOV R6, #0x55
STR R6, [R5]
.align
PAaddr: .word 0x400043FC
Disassembly of section .text:
00000000 <PAaddr-0x8>:
0: 4d01 ldr r5, [pc, #4] ; (8 <PAaddr>)
2: 2655 movs r6, #85 ; 0x55
4: 602e str r6, [r5, #0]
6: bf00 nop
00000008 <PAaddr>:
8: 400043fc .word 0x400043fc
没有变化,但
.cpu cortex-m3
.syntax unified
.thumb
LDR R5, PAaddr
MOV R6, #0x55
STR R6, [R5]
.align
PAaddr: .word 0x400043FC
Disassembly of section .text:
00000000 <PAaddr-0x8>:
0: 4d01 ldr r5, [pc, #4] ; (8 <PAaddr>)
2: f04f 0655 mov.w r6, #85 ; 0x55
6: 602e str r6, [r5, #0]
00000008 <PAaddr>:
8: 400043fc .word 0x400043fc
和
.cpu cortex-m3
.syntax unified
.thumb
nop
LDR R5, PAaddr
MOV R6, #0x55
STR R6, [R5]
.align
PAaddr: .word 0x400043FC
Disassembly of section .text:
00000000 <PAaddr-0xc>:
0: bf00 nop
2: 4d02 ldr r5, [pc, #8] ; (c <PAaddr>)
4: f04f 0655 mov.w r6, #85 ; 0x55
8: 602e str r6, [r5, #0]
a: bf00 nop
0000000c <PAaddr>:
c: 400043fc .word 0x400043fc
ALIGN(0x02+2,4(=0x04。0x0C-0x04=0x08,2个字,0x4D02编码。
您可以使用Kiel的汇编语言与上面显示的gnu做同样的事情。
除非你正在编写自己的汇编程序(或者出于其他原因试图创建自己的机器代码(,否则你的工作不是计数。
在任何情况下,只需阅读有关体系结构的ARM体系结构文档。将其与经过调试的汇编程序的输出进行比较,以便根据需要进行进一步的说明。
编辑
来自早期/原始ARM ARM
address = (PC[31:2] << 2) + (immed_8 * 4)
Rd = Memory[address, 4]
这个更有意义IMO.
当有疑问时,请返回旧的/原始的ish ARM ARM。
最新的ARM ARM
if ConditionPassed() then
EncodingSpecificOperations(); NullCheckIfThumbEE(15);
base = Align(PC,4);
address = if add then (base + imm32) else (base - imm32);
data = MemU[address,4];
if t == 15 then
if address<1:0> == ‘00’ then LoadWritePC(data); else UNPREDICTABLE;
elsif UnalignedSupport() || address<1:0> == ‘00’ then
R[t] = data;
else // Can only apply before ARMv7
if CurrentInstrSet() == InstrSet_ARM then
R[t] = ROR(data, 8*UInt(address<1:0>));
else
R[t] = bits(32) UNKNOWN;
但这涵盖了T1、T2和A1在一个镜头中的编码,使其最令人困惑。
在任何情况下,它们都描述了编码的情况以及每个指令的总体大小。