我找不到这个问题的答案.你可以告诉我ARM架构何时从手臂模式切换到拇指模式?解释切换工作的所有方式.
我有一些ARM代码,我试图在Cortex M3上运行.我用Thumb编写的大部分代码都是用C语言编写的 - 但对于某些函数,我希望能够运行普通的ARM代码(据我所知,这在M3上是可行的吗?).
所以...
原始C代码和汇编:
int donothing(int a) {
return a;
}
00000068 <donothing>:
68: e52db004 push {fp} ; (str fp, [sp, #-4]!)
6c: e28db000 add fp, sp, #0
70: e24dd00c sub sp, sp, #12
74: e50b0008 str r0, [fp, #-8]
78: e51b3008 ldr r3, [fp, #-8]
7c: e1a00003 mov r0, r3
80: e28bd000 add sp, fp, #0
84: e8bd0800 ldmfd sp!, {fp}
88: e12fff1e bx lr
Run Code Online (Sandbox Code Playgroud)
编译使用 arm-none-eabi-gcc -mfloat-abi=soft -nostdinc -nostdlib
我转而使用blx r4
- 如果基地址&3为0,它应该交换.
在GDB中逐步执行此操作,即使地址包含正确的数据,它也会一旦到达显示的行,就会进入HardFaults.
(gdb) …
Run Code Online (Sandbox Code Playgroud) 我试图通过使用拇指指令来缩小我的iOS应用程序(二进制代码的代码部分为70 MB)。关于使用armv7的拇指版本,似乎有很多讨论,例如:http ://wanderingcoder.net/2010/07/19/ought-arm/ 。但是,我找不到关于arm64 + Thumb的太多信息。可能吗 如果是这样,我该如何用clang进行编译?
作为练习,我想让 STM32F103 从内部 SRAM 执行。这个想法是手工编写一些 THUMB 程序集,用 组装它arm-none-eabi-as
,用 OpenOCD 的mwh
指令将机器代码加载到 SRAM 中,用将 PC 设置为 SRAM 的开头reg pc 0x20000000
,最后step
几次。
这是我要执行的汇编代码。这基本上是一个毫无意义的循环。
# main.S
.thumb
.syntax unified
mov r0, #40
mov r1, #2
add r2, r0, r1
mvn r0, #0x20000000
bx r0
Run Code Online (Sandbox Code Playgroud)
我需要获取机器码以便我可以将其加载到 SRAM 中,但是反汇编器输出似乎不正确。
$ arm-none-eabi-as -mthumb -mcpu=cortex-m3 -o main.o main.S
$ arm-none-eabi-objdump -d -m armv7 main.o
main.o: file format elf32-littlearm
Disassembly of section .text:
00000000 <.text>:
0: f04f 0028 mov.w r0, #40 ; …
Run Code Online (Sandbox Code Playgroud) 我阅读了几篇文章,其中包括 SO为什么 ARM PC 寄存器指向下一个要执行的指令之后的指令?,该 pc 寄存器值实际上是当前执行指令地址加上前面的 2 条指令,因此在 ARM 状态下它是 +8 字节(2*32 位)。
我的问题是,对于拇指状态,可能有 16 位或 32 位指令,这是否意味着对于 16/32 位指令,获取 pc 地址可能是 +4 字节或 +8 字节的偏移量?
例如:
279ae6: f8df 9338 ldr.w r9, [pc, #824] --> pc value= 279aea or 279aee
279aea: f44f 7380 mov.w r3, #256
279aee: 48cd ldr r0, [pc, #820]
Run Code Online (Sandbox Code Playgroud)
我使用以下代码进行了更多测试:
1598: 467b mov r3, pc
159a: f8bf 4000 ldrh.w r4, [pc] ; 159c
159e: 46f9 mov r9, pc
15a0: f83f 5001 ldrh.w r5, [pc, …
Run Code Online (Sandbox Code Playgroud) 以下命令
/usr/bin/arm-linux-gnueabihf-gcc -O3 -DNDEBUG -march=armv7-a -mfloat-abi=hard -fPIC -fno-builtin -fno-exceptions -fomit-frame-pointer -funwind-tables -fno-stack-protector -fvisibility=hidden -fvisibility-inlines-hidden -fno-function-sections -fno-lto -g -Wno-variadic-macros -Wno-non-virtual-dtor -o testAsm.S.o -c testAsm.S
Run Code Online (Sandbox Code Playgroud)
在以下程序集文件中testAsm.S
:
.syntax unified
.arch armv7
.fpu vfpv3
.code 32
.global _functionPointer
.p2align 2
.global _asmFunction
.type _asmFunction, %function
_asmFunction:
PUSH {r1-r3,lr}
VPUSH {d0-d7}
MOVW r1,#:lower16:_functionPointer
MOVT r1,#:upper16:_functionPointer
LDR r2, [r1]
CMP r2, #0
BEQ asmFunction_restore
MOV r1, #0
BLX r2
asmFunction_restore:
VPOP {d0-d7}
POP {r1-r3,pc}
Run Code Online (Sandbox Code Playgroud)
每条指令产生以下错误
错误:尝试在仅Thumb处理器上使用ARM指令
具体来说,下面是输出:
testAsm.S: Assembler messages:
testAsm.S:10: Error: attempt to …
Run Code Online (Sandbox Code Playgroud) MOV R0, #0x80000000
MOV R1, #0x1
SUBS R2, R1, R0
Run Code Online (Sandbox Code Playgroud)
运行此代码后,将设置标志 N 和 Z。现在,我知道如果运算结果为负,则设置 N 标志,而当发生溢出时设置 Z 标志。
我不明白的是,如何0x1 - 0x80000000
导致溢出。任何帮助表示赞赏!
如果我有一个ARM Thumb 2指令流,如下所示:
itt NZ
mov r1,r2
it MI
mov r3,r4
Run Code Online (Sandbox Code Playgroud)
第一个IT指令的IT块包含mov
第二个IT指令it
.这个序列是允许的,还是未定义的行为?
所以现在我读了《ARM Cortex-M3/M4 权威指南》一书,无法理解为什么 16 位指令无法访问高级通用寄存器 R8-R12。
它说实际上很少有人可以访问这些寄存器,但大多数不能。