MIPS编程:
汇编语言
#include:利用C预编译器cpp提供的功能,为常数定义一些简单的文本替代宏操作。
.set:指导汇编器如何工作(排列指令顺序)。.set noreorder将底层的分支延迟槽暴露出来,那么我们就必须确保加载的数据不被紧接着的指令使用。
LEAF是在mips/asm.h中定义的宏,用于定义简单的例程,非LEAF例程需要大量的工作来存储变量,返回地址等信息。
句法:标号和变量的标识符可以是C语言中的合法标识符,同时可以包含“$”和“.”。MIPS汇编语言中并没有对应于C语言“指针”的操作符,但当汇编器需要一个指针大小的数据时,会用一个标号来代替。“.”表示当前指令或数据声明的地址,甚至对它们进行一些简单数学运算。在带常量(立即数)的计算指令中,一般的算术指令立即数都采用符号扩展,逻辑操作都采用补0扩展。
寻址模式:硬件只支持一种寻址方式,基址寄存器+偏移,然而,汇编器会调整代码,可以以多种方式寻址:
直接寻址:数据标号或者外部变量名
直接+索引:以标号位置为基准,由寄存器指定偏移量
常量:大数,绝对32位长地址
寄存器间接寻址:基址寄存器+偏移
目标文件和内存布局:
ROM程序的目标代码段和典型内存布局入下图所示。_ftext为代码段起始点;etext为代码段结束点;_fdata为初始化数据起始点;edata为初始化数据结束点;_fbss未初始化数据段起始点;end为未初始化数据结束点。
C和其他程序语言的编译器都是将整个程序划分为许多模块,分别编译。为了使彼此能配合操作系统工作,编译的代码模块之间遵循一些调用接口约定(由编译器强制,因此汇编程序员也强制),包括寄存器的使用,堆栈建立和参数传递等。
MIPS没有专门的I/O指令,这说明I/O操作和所选地址的普通的加载存储操作一样。关键字volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据。如果没有volatile关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值,如果这个变量由别的程序更新了的话,将出现不一致的现象。用C写设备驱动比汇编容易,但使用中要注意合理选择。特别要注意了解工具链的工作方式,如何在你的高级语言代码中嵌入低级汇编指令,并确保系统按照你期望的方式运行。
阅读(2317) | 评论(0) | 转发(0) |