关于 Cortex-M3的汇编指令

在 Cortex-M3 中,有专门的指令负责堆栈操作——PUSH 和 POP。它俩的汇编语言语法如下例所

演示

PUSH {R0} ; *(--R13)=R0。R13 是 long*的指针

POP {R0} ; R0= *R13++

PUSH 和 POP 还能一次操作多个寄存器

PUSH {R0-R7, R12, R14} ; 保存寄存器列表

… ; 执行处理

POP {R0-R7, R12, R14} ; 恢复寄存器列表

BX R14 ; 返回到主调函数

寄存器的 PUSH 和 POP 操作永远都是 4 字节对齐的——也就是说他们的地址必须是0x4,0x8,0xc,……。事实上,R13 的最低两位被硬线连接到 0,并且总是读出 0(Read As Zero)。

R14 是连接寄存器(LR)

关于 Cortex-M3的汇编指令_第1张图片

 

main ;主程序

BL function1 ; 使用“分支并连接”指令呼叫 function1

; PC= function1,并且 LR=main 的下一条指令地址

… Function1

… ; function1 的代码

BX LR ; 函数返回(如果 function1 要使用 LR,必须在使用前 PUSH,

; 否则返回时程序就可能跑飞了——译注)

CM3 内部使用了指令流水线,读 PC 时返回的值是当前指令的地址+4。比如说:

0x1000: MOV R0, PC ;        R0 = 0x1004

PUSH {R0-R3, LR}

POP {R0-R3, PC}

请注意:POP 的最后一个寄存器是 PC,并不是先前 PUSH 的 LR。这其实是一个返回的小技巧。与其按部就班地把先前 LR 的值弹回 LR,再复制给 PC 来返回;不如干脆绕过 LR,直接传给 PC!那不怕 LR 的值没有被恢复吗?不怕,因为 LR 在子程序调用中的唯一用处,就是在返回时提供返回地址。因此,在返回后,先前保存的返回地址就没有利用价值了,所以只要PC 得到了正确的值,不恢复也没关系。

标号

操作码 操作数 1, 操作数 2, … ;注释

立即数必须以“#”开头,如

MOV R0, #0x12 ;   R0写入0x12

MOV R1, #’A’ ;  R1写入字母 A 的 ASCII 码值

还可以使用 EQU 指示字来定义常数,然后在代码中使用它们,例如:

NVIC_IRQ_SETEN0 EQU 0xE000E100 ; 注意:常数定义必须顶格写

NVIC_IRQ0_ENABLE EQU 0x1

LDR R0, =NVIC_IRQ_SETEN0 ;在这里的 LDR 是个伪指令,它会被汇编器转换成

一条“相对 PC 的加载指令”

MOV R1, #NVIC_IRQ0_ENABLE ; 把立即数传送到 R1 中

STR R1, [R0] ; *R0=R1,执行完此指令后 IRQ #0 被使能。

LDR R3, =MY_NUMBER ; R3= MY_NUMBER

LDR R4, [R3] ; R4= *R3

LDR R0, =HELLO_TEXT ; R0= HELLO_TEXT

BL PrintText ; 呼叫 PrintText 以显示字符串,R0 传递参数

你可能感兴趣的:(arm)