在开发操作系统过程中,有时必须使用某些特殊的指令(如inb/outb/hlt),而C编译器无法自动使用这些指令。
因此,如果要使用这些指令,有两种方式:
-
1.在汇编文件中为该指令的使用创建汇编函数(子程序),然后在C代码中以函数调用的方式去使用;
-
2.使用内联汇编:即在C代码中嵌入汇编程序。
在大多数情况下,使用内联汇编会更加简单、易用。因此,这里用GCC内联汇编的写法。
内联汇编格式参考链接:https://www.cnblogs.com/shuijiaoa/p/16060156.html
一些说明
(1)const 关键字
关键字const用来定义常量,如果一个变量被const修饰,那么它的值就不能再被改变.
与预编译指令相比,const修饰符有以下的优点:
1、预编译指令只是对值进行简单的替换,不能进行类型检查
2、可以保护被修饰的东西,防止意外修改,增强程序的健壮性
3、编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。
参考链接:https://blog.csdn.net/xingjiarong/article/details/47282255
(2)函数参数为常量的好处
函数的参数,如果定义为常量,
意味着在函数内部对该参数的任何尝试修改都应该被禁止,以保持其值的稳定性。
这种设计有助于确保函数的行为可预测,避免因参数值变化导致的意外结果。
(3)函数参数为常量时,调用函数仍然能改变参数值
C语言的“常量”指的是字面值常量,例如const int a = 10;中的10。而a称为常变量,它本质上是一个不能改变的变量。
这种不能改变的特性是语法层面的,编译器通过语法检查来确保a没有在代码中被修改过。
在运行时没有任何机制确保a不被修改,它就和任何普通变量一样。
链接:https://www.zhihu.com/question/372226898/answer/1018899469
(4)在C语言中\n 和 \r 区别
-
\n:代表换行符(newline),其主要作用是将光标移动到下一行的开头。在C语言编程中,\n用于输出文本时,会在当前位置插入一个换行符,使得接下来的文本从下一行的开头开始输出。
-
\r:代表回车符(carriage return),其主要作用是将光标移动到当前行的开头。在C语言中,\r用于输出文本时,会在当前位置插入一个回车符,使得光标回到当前行的开头,而不是换行。
实操(编写loader_entry函数中的显示字符串的功能)
loader_16.c
__asm__(".code16gcc");
//显示字符串的函数
static void show_msg(const char * msg){
//循环的读取字符
char c;
while( (c = *msg++) != '\0' ){ //*(解引用运算符)的优先级比 ++(自增运算符)的优先级高
asm(
"mov $0xe , %%ah\n\t" //寄存器要加两个%符号
"mov %[ch] , %%al\n\t"
"int $0x10"::[ch]"r"(c) //r代表任意寄存器,把ch字符存入任意寄存器中,并将c映射到该寄存器中
);
}
}
void loader_entry(void){
show_msg("....loading....\n\r");
for(;;){}
}
编译运行调试后:
为了避免编译器优化代码,可以加上volatile关键字:
标签:汇编,const,常量,04,loader,编译器,内联 From: https://www.cnblogs.com/kakafa/p/18318975