day4
汇编代码初始化系统中:
为什么要保存cpsr:要把其他的状态还原 如(N Z)
user:
mov r0,#3
cmp r0,#4
... //irq
movlt r1,#5
irq:
mov r0,#10
cmp r0,#10
moveq r2,#6
fiq和irq的区别:
fiq和irq的区别:
1.fiq有自己独立的寄存器
2.fiq比irq快
b reset
b und
...
b irq
b fiq
fiq:
xxx...(b fiq之后会立刻运行fiq 马上就是xxx,只需要pc+4就可以执行了)
irq:
xxx...(irq 需要跳转)
3.fiq可以打断irq,irq不能打断fiq
共享内存
data: .space 64
mov r0, #10
ldr r1,=data
str r0,[r1]
mov r0,#5
ldr r0,[r1]
.globl _start
_start: b reset
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq
_undefined_instruction: .word _undefined_instruction
_software_interrupt: .word swi_handler
_prefetch_abort: .word _prefetch_abort
_data_abort: .word _data_abort
_not_used: .word _not_used
_irq: .word _irq
_fiq: .word _fiq
reset:
/*set the cpu to SVC32 mode */
mrs r0, cpsr
bic r0, r0, #0x1f
orr r0, r0, #0xd3
msr cpsr,r0
/* Set vector address register */
ldr r0, =_start
mcr p15, 0, r0, c12, c0, 0 @Set VBAR
/*设置svc的栈顶指针*/
ldr sp , stacktop
/*set the cpu to software_interrupte mode */
mrs r0 , cpsr
bic r0 , r0 , #0x1f
orr r0 , r0 , #0xd0
msr cpsr,r0
/*设置user的栈顶指针*/
ldr sp,stacktop
sub sp,sp,#256
bl _main
stack: .space 256*8
stacktop: .word stack+256*8
data: .space 64
_main:
mov r1,#10
mov r2,#3
ldr r7,=data
str r1,[r7]
str r2,[r7,#4]
mov r1,#66
mov r2,#44
bl user_sub
ldr r3,[r7,#8]
bl user_add
ldr r3,[r7,#8]
nop
nop
user_sub:
stmfd sp!,{r0-r12,lr}
swi 0x1
ldmfd sp!,{r0-r12,pc}
user_add:
stmfd sp!,{r0-r12,lr}
swi 0x2
ldmfd sp!,{r0-r12,pc}
swi_handler:
stmfd sp!,{r0-r12,lr}
ldr r5,[lr,#-4]
bic r5,r5,#0xff000000
cmp r5,#0x1
bleq swi_sub
cmp r5,#0x2
bleq swi_add
ldmfd sp!,{r0-r12,pc}^
swi_sub:
stmfd sp!,{r0-r12,lr}
ldr r7,=data
ldr r1,[r7]
ldr r2,[r7,#4]
sub r1,r1,r2
str r1,[r7,#8]
ldmfd sp!,{r0-r12,pc}
swi_add:
stmfd sp!,{r0-r12,lr}
ldr r7,=data
ldr r1,[r7]
ldr r2,[r7,#4]
add r1,r1,r2
str r1,[r7,#8]
ldmfd sp!,{r0-r12,pc}
1.混合编译
1.函数的参数
如果用C代码写函数,函数定义在汇编当中时,参数列表有r0,r1,r2,r3来获取
如果参数列表过多,只有前四个参数可以给寄存器,剩下的全部放在内存中
2.函数的返回值:r0给C
.global _start
.global user_add
.global user_sub
_start: b reset
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq
_undefined_instruction: .word _undefined_instruction
_software_interrupt: .word swi_handler
_prefetch_abort: .word _prefetch_abort
_data_abort: .word _data_abort
_not_used: .word _not_used
_irq: .word _irq
_fiq: .word _fiq
reset:
/*set the cpu to SVC32 mode */
mrs r0, cpsr
bic r0, r0, #0x1f
orr r0, r0, #0xd3
msr cpsr,r0
/* Set vector address register */
ldr r0, =_start
mcr p15, 0, r0, c12, c0, 0 @Set VBAR
/*设置svc的栈顶指针*/
ldr sp , stacktop
/*set the cpu to software_interrupte mode */
mrs r0 , cpsr
bic r0 , r0 , #0x1f
orr r0 , r0 , #0xd0
msr cpsr,r0
/*设置user的栈顶指针*/
ldr sp,stacktop
sub sp,sp,#256
bl main
stack: .space 256*8
stacktop: .word stack+256*8
data: .space 64
user_sub:
stmfd sp!,{r1-r12,lr}
ldr r7,=data
str r0,[r7]
str r1,[r7,#4]
swi 0x1
ldr r0,[r7,#8]
ldmfd sp!,{r1-r12,pc}
user_add:
stmfd sp!,{r1-r12,lr}
ldr r7,=data
str r0,[r7]
str r1,[r7,#4]
swi 0x2
ldr r0,[r7,#8]
ldmfd sp!,{r1-r12,pc}
swi_handler:
stmfd sp!,{r0-r12,lr}
ldr r5,[lr,#-4]
bic r5,r5,#0xff000000
cmp r5,#0x1
bleq swi_sub
cmp r5,#0x2
bleq swi_add
ldmfd sp!,{r0-r12,pc}^
swi_sub:
stmfd sp!,{r0-r12,lr}
ldr r7,=data
ldr r1,[r7]
ldr r2,[r7,#4]
sub r1,r1,r2
str r1,[r7,#8]
ldmfd sp!,{r0-r12,pc}
swi_add:
stmfd sp!,{r0-r12,lr}
ldr r7,=data
ldr r1,[r7]
ldr r2,[r7,#4]
add r1,r1,r2
str r1,[r7,#8]
ldmfd sp!,{r0-r12,pc}
/*===============================================
* 文件名称:main.c
* 创 建 者: memories
* 创建日期:2023年06月25日
* 描 述:have a nice day
================================================*/
#include <stdio.h>
int main(int argc, char *argv[])
{
int a = 100;
int b = 200;
int c = user_add(a,b);
}
链接文件:
ENTRY(_start)
SECTIONS{
. = 0x0;
.text : {
test.o(.text)
*(.text)
}
.data : {
*(.data)
}
.bss : {
*(.bss)
}
}
混合编译的意义:
all:
arm-linux-gcc sub_test.s -o test.o -c -g
arm-linux-gcc main4.c -o main4.o -c -g
arm-linux-ld test.o main4.o -o test.elf -Ttest.lds
arm-linux-ld test.o -o test.elf -Ttest.lds
qemu-system-arm -machine xilinx-zynq-a9 -m 256M -serial stdio -kernel test.elf -S -s
arm-linux-objcopy test.elf test.bin -O binary
汇编运行速度很快,但是晦涩难懂,所以一般是函数初始化或者系统初始化的时候需要写汇编,可以快速完成任务,其他功能还是需要写C语言,方便人理解
pc的作用:
dd(a,b);
}
## 链接文件:
```tex
ENTRY(_start)
SECTIONS{
. = 0x0;
.text : {
test.o(.text)
*(.text)
}
.data : {
*(.data)
}
.bss : {
*(.bss)
}
}
混合编译的意义:
汇编运行速度很快,但是晦涩难懂,所以一般是函数初始化或者系统初始化的时候需要写汇编,可以快速完成任务,其他功能还是需要写C语言,方便人理解
pc的作用: