操作系统L5学习笔记(哈工大李治军老师)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

在B栈有李治军老师的视频:操作系统(哈工大李治军老师)32讲(全)超清
其中李老师讲的是Linux0.11源码

linux 0.11源码(含注释)—无需积分:https://blog.csdn.net/m0_37984066/article/details/108881812
BIOS系统服务 —— 直接磁盘服务(int 0x13):https://blog.csdn.net/cherisegege/article/details/79835737
《Linux内核设计的艺术》学习笔记(五)INT 0x10中断:https://www.bbsmax.com/A/A2dmMxjbde/

实验二:
https://codetd.com/ja/article/13499331


提示:以下是本篇文章正文内容,下面案例可供参考

一、IDT中断描述符表

在这里插入图片描述

示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。
IDT 表中可以存放三种类型的门描述符:

  • 中断门描述符
  • 陷阱门描述符
  • 任务门描述符

在这里插入图片描述
在这里插入图片描述

#define _syscall3(type, name, atype a, btype, b, ctype c) \
type name(atype a, btype b, ctype c) \
{   long  __res; \
    __asm__ volatile("int 0x80":"=a"(__res):""(__NR_##name), \ /* "=a"(__res)表明输出__res = %eax,""(__NR_##name)表明输入movl __NR_##name, %eax */
    "b"((long)(a)), \ /* 输入: movl a, %ebx,a即为atype a */
    "c"((long)(b)), \ /* 输入: movl b, %ecx,b即为btype b */
    "d"((long)(c))); \ /* 输入: movl c, %edx,c即为ctype c */
    if (__res >= 0) \
        return (type)__res; \
    errno = -__res; \
    return -1; \
}

32位cpu的系统调用:

  • %eax表用系统调用表序号,unistd.h
  • 传递参数使用寄存器的顺序:%ebx, %ecx, %edx, %esi,%edi;多于5个参数使用其他方式传递

对于write系统函数调用,宏展开后为:

/* 0ff_t表示文件偏移量,一般是long类型 */
int write(int fd, const char *buf, off_t count)
{
    long __res;
    __asm__ volatile("int 0x80":"=a"(__res):""(__NR_##write),  \/* 在32位CPU中宏__NR_write等于4,64为CPU中__NR_write等于1 */
    "b"((long)(fd)), \
    "c"((long)(buf)), \
    "d"((long)(count)));
    ......
}

int 0x80中断的处理

void sched_init(void)
{
    set_system_gate(0x80, &system_call);
    ......

显然,set_system_gate用来设置0x80的中断处理
在linux/include/asm/system.h中


#define _set_gate(gate_addr,type,dpl,addr) \
__asm__ ("movw %%dx,%%ax\n\t" \
	"movw %0,%%dx\n\t" \
	"movl %%eax,%1\n\t" \
	"movl %%edx,%2" \
	: \
	: "i" ((short) (0x8000+(dpl<<13)+(type<<8))), \  // %0, "i":输入
	"o" (*((char *) (gate_addr))), \  // %1,"o":输出
	"o" (*(4+(char *) (gate_addr))), \ // %2,"o":输出
	"d" ((char *) (addr)), \// %3,"d":%edx初始值
	"a" (0x00080000))      // %4,"a":%eax初始值

#define set_system_gate(n, addr) _set_gate(&idt[n],15,3,addr)

汇编注释:

  • mov :为寄存器移动指令,例如movw dx,ax 即为dx-〉ax,mov为移动指令。“w”为长度的指定w=word=16位=2个字节;相应的“l”=long=32位=4字节。
  • % :AT&T汇编在引用寄存器时要在前面加1个%,%%是因为GCC在编译时会将%视为特殊字符,拥有特殊意义,%%仅仅是为了汇编的%不被GCC全部转译掉
  • ax 与 eax :ax与eax之间是有联系的,他们并不是孤立的,eax为32位寄存器,ax为16位寄存器,而ax就是eax的低16位。dx与edx具有相同的关系。
  • %0、%1、%2、%3:0、1、2、3可以看作变量,这些变量在程序的":“之后,程序的两个”:",是定义输入、输出项的。针对这段程序这些变量的前面都加了明确的限定,例如"i"(输入项)、“o”(输出项),剩下的"d"(edx的初始值),“a”(eax的初始值)。而0、1、2、3的概念就是指第几个变量,这里输入项、输出向、寄存器初始混合编号;相应的0(“i”((short)(0x8000+(dpl<<13)+(type<<8)))));1((*((char )(gate_addr))));2(((4+(char *)(gate_addr))));3(“d”((char *)(addr)));4(“a”(0x00080000))
  • <<:这是个运算符,如果大家觉得<<不好理解可以用乘2的次方来实现相同的效果,例如14<<13=14*2的13次方
  • \n\t:这是嵌入式汇编一种书写格式
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值