链接
简单的ld链接脚本学习 - 简书 (jianshu.com) !!!!!!!!!!很棒
RISC-V汇编快速入门 | Half Coder (gitee.io) !!!!!!!!!!!!!!很棒
任务
PROVIDE关键字:
该关键字定义一个(目标文件内被引用但没定义)符号。相当于定义一个全局变量,其他C文件可以引用它。
SECTIONS
{
.text :
{
*(.text)
_etext = .;
PROVIDE(etext = .);
}
}
如上,目标文件可以引用etext符号,其地址为定义为.text section之后的第一个字节的地址。C文件中引用。
int main()
{
//引用该变量
extern char _etext;
//...
}
LD文件最容易出的问题
忘记分号;
空格不对,
PROVIDE(_rodata_end = .);// 正确
PROVIDE(_rodata_end= .);// x
PROVIDE(_rodata_end =.);// x
.data : {// 正确
.data:{// 错误
RISC-V汇编
.global
.global symbol_name(.globl symbol_name):
定义一个全局的符号,使得链接器能够全局识别它,即一个程序文件中定义的符号能够被其他所有程序文件所见,一般用于定义程序的入口标签。与之对应的还有.local symbol_name。
.align
.align integer
将当前PC地址推进到2的integer次方字节对齐的位置。假设.align 3 即将当前的PC地址推进到8个字节对齐的位置处。如果当前位置PC为8000a002,则下一条指令的PC地址将被推进到8000a008。
.4byte
.4byte expression,...
将从当前PC地址开始分配若干个4字节的空间,例如.4byte 0x87a2 而当前PC地址为8000a003,则编译链接时会从8000a003开始申请一个4byte空间(8000a003~8000a006)用来存放0x87a2,因数据只有2byte,而空间有4byte,所以高位会被补零。也可以使用.4byte 0x2233aa55,0x23,0x3443334,0x5a这样的方式一次申请4个4byte空间,当然也可以申请n个。除了常见的.4byte外还会有.2byte,.byte,.word,.half,.dward等。
.macro和.endm
用来定义一个宏。
.text /.data /.rodata /.bss
基本等同于.section .text/.data/.rodata/.bss。
.opthon
.opthon {rvc,norvc,push,pop}
设定某些架构的特定选项,像.option rvc表示接下来的汇编程序可以被汇编生成压缩指令。
文本标签和数字标签
在程序跳转时大部分会跳转到标签,标签分两种,文本标签和数字标签,区别是文本标签是全局可见的,标签名必须独一无二,而文本标签属于局部标签,命名时可以重复。
ret和mret的区别
ret
通过ra寄存器返回
mret
通过mepc
mepc和mscratch分别装的是什么
mepc
装的是某个任务具体到哪指令的地址
mscratch
装的是某个任务上下文的基地址
!mscratch寄存器本质上是一个用户可以自定义的寄存器,仅仅是本系统赋予某个任务上下文的基地址的作用
为什么要保存临时寄存器的值?
猜想:
临时寄存器的临时概念是针对任务这个尺度,对于一个任务,使用临时寄存器是要保证先赋值再使用。
而对于系统层面,任务可能在一半就被切换到另一个任务了,而可能临时寄存器的值还没用完。
所以对于系统来说,任务切换时必须保证临时寄存器的值要保存是吧?
回答:
不是的,实际区别是在指令级别,callee和caller