自己动手写操作系统心得---转

来源:互联网 发布:大连保险网络大学答案 编辑:程序博客网 时间:2024/06/16 19:11

1 先说对变量、标签的使用和命名

汇编中有几种对地址标签的分法,算是在概念上的分类,方便大家的理解。

分别为:

  • LABEL
  • 变量名

LABEL:

意思是我指向的就是一大块的首地址,使用方法:LABEL_NAME:(注意后面要加冒号)
命名方式,尽量使用Java中的类似于包的命名方式,比如LABEL_SEG_CODE16,LABEL_SEG_CODE32,LABEL_DESC_STACK。

汇编中的LABEL还有一种叫做,局部LABEL,是以(点)开头,比如.begin,.1,.2。在不同的段中可以使用相同的带点开头的LABEL,不会重复。
并且经过实验,最好只用在代码段中,数据段不好使。

变量名:

变量名分为函数变量名和普通变量名

  • 函数变量名:
    指的是一个SUB_RUTIN的首地址。比如DispStr,使用的时候是call DispStr,然后在声明时候因为它本来就是一个地址,就是用上面标签的同样的声明方式。DispStr:(注意后面有冒号)
  • 普通变量名:
    分为2种形式构成的变量名,
    第一种使用equ生成的纯的变量,貌似是宏,比如:TopOfStack    equ    $ - LABEL_STACK - 1,命名方式为首字母大写(也不一定,如果刻意代表DataSeg的存储空间,)。
    第二种使用db dd dw生成的变量,其实就是一个地址。生成的各种变量分别指向的是不同的数据类型,那么命名时候前几个字母尽量写清楚类型。
    比如如下的命名:(特别是数据段会有这种命名方式的用法,冒号可加可不加)
    _dwDispPos:            dd    (80 * 6 + 0) * 2
    _wSPValueInRealMode        dw    0

    _szRAMSize            db    "RAM size:", 0
  • 补充:db 代码下面我所输入的这一串字符,每一个字符占一个字节。

2  依次对各个问题进行分析,首先为何在16位代码段中会有:mov    dword [_dwMCRNumber], 0-----------这个dword在这里的必要性是什么?
答:16位代码段中默认[_dwMCRNumber]这个地址,指向的是一个2个字节1个字,也就是说上面的那个指令,如果没有dword,只会改变内存中的2个字节赋值为0,现在加上dword之后,就会改变4个字节了,相应的word,byte也是这个作用。当然在32位代码段中,默认是改变4个字节的。

3 变量在32位中和16位中所占字节的区别?
答:16位代码段中默认该变量是占2字节,(不论该变量是一个地址还是一个值

4 mov同一个地址在mov ax,[100]与mov eax,[100]的不同之处?
答:这里不论是在32位代码段还是16位代码段中,虽然100指向的是同一处地址,但是因为mov到寄存器分别是16位的ax和32位的eax,那么最后第一个命令中只会改变ax的16位,第一个命令中会改变eax的整个32位,也就是说在这两个命令中[100]所指向的数据是不一样的,第一个命令中是2字节的,第二个命令中是4字节的。

5 在汇编中不能出现相同的LABEL,否则汇编时候会出现redefine的错误。

6 在汇编中[BITS 16]和[BITS 32]各代表什么意思?
答:[BITS 16]代表下面这个段是按照16位进行编译的,代码地址(比如一个label)都是16位的(2字节的)。[
BITS 32]代表下面的地址都是32位的。

7 ALIGN 32在每个代码段首处是什么意思?
ALIGN是数据对齐的意思,就是说将这个代码段的段首地址对齐到32字节处,以前学过对齐到4字节,处理起来访问内存速度会比较快。这里32不知道什么用意,不过反正访问速度变快了。

8 32位中的代码段中的label标签是偏移量还是实地址?
答:这个是不一定的。按理说所有的这些label标签都应该是地址,如果是16位代码就是16位地址,32位代码就是32位地址。但是在使用的时候会发生一些差异,

  • 比如在数据段中的标签,全部都是实模式中的地址,并且在使用这些地址的时候,一般都是 mov [ds:addr], ax等等的用法,所以如果是实模式,它可以是编译时产生的纯地址,而如果是保护模式我们希望他是相对数据段首地址的偏移量,所以一般要重新计算一个地址偏移量offset给保护模式使用。
  • 如果是函数段的标签地址,如果是在同一个段内调用的话,那就是NASM汇编器会自动计算出偏移量,直接call到偏移量那去了,比如call .3(看过反编译的代码的).如果不是同一个保护模式的段,那么:经过分析,貌似当使用call这种命令的时候,函数地址都会被汇编成离段首的偏移量。这样就可以放心大胆的调用某个段的函数地址了。

9  ret retf iref的不同是什么?
答:

  • ret  弹出一个参数,给ip,返回
  • retf 弹出2个参数,一个给 ip,一个给 cs
  • iref 弹出 3个参数,一个给 ip,一个 给 cs ,一个 个 flag标志位

他们都是返回调用点的,看你调用的时候,用的什么调用的,是 call 段内转移  ,还是call 段间转移,还是int 调用中断

10  假如段A中有个地址LABEL_FUNC_A,段B中有个地址LABEL_FUNC_B,那么在函数保护模式和在实模式下分别该如何被调用
答:

  1. 同一个段内:
    • 使用call:保护模式下,实模式下均可直接call label。
    • 使用jmp:保护模式下,实模式下均可直接jmp label。
  2. 段间的调用:
    • 使用jmp:实模式下可直接cs:label(大部分实模式代码都在同一个一个cs下),保护模式下因为cs中存储的是selector,语法为:cs:offset
    • 使用call:实模式下可直接cs:label(大部分实模式代码都在同一个一个cs下),保护模式下因为cs中存储的是selector,语法为:cs:offset


11 为什么gdt表中的段基地址非要等到代码初始化的时候才能填入?
答:

因为平时我们只知道实模式下的LABEL_SEG,其实是实模式下的概念cs段的偏移量,实模式下cs,ds,es,ss神马的都在一个段内(至少我现在写的小代码是这个样子),需要在运行的时候将ds与LABEL_SEG相合并形成真正的地址,再赋值到selector中的段基地址处。

12 在写代码的时候,因为好多int中断都会使用到es,所以不能保证在函数中es永远等于自己想要的ds,必须显示的赋值。

答:es在使用的时候,必须确定它的值是否一定是当前想要的段地址。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 5个月宝宝腿短怎么办 5个月宝宝太瘦怎么办 宝宝喝了浓奶粉怎么办 一岁把尿不尿怎么办 五个月的宝宝大便干燥怎么办 婴儿便秘怎么办什么方法最有效 8个月小孩便秘怎么办 1个月新生儿便秘怎么办 新生儿头竖立0分怎么办 20天的宝宝便秘怎么办 出生23天的宝宝便秘怎么办 喝奶粉的宝宝便秘怎么办 抱孩子抱的驼背怎么办 4岁宝宝不拉屎怎么办 小朋友大便拉不出来怎么办 儿童便秘拉不出来怎么办 没感冒喉咙有痰怎么办 宝宝喂不进去药怎么办 新生儿只放屁不拉大便怎么办 新生儿腹胀不拉大便怎么办 8月宝宝咳嗽有痰怎么办 2个月婴儿惊吓怎么办 吃了米粉不拉屎怎么办 奇异果奶昔苦了怎么办 8个月宝宝偏瘦怎么办 一岁宝宝螺旋腿怎么办 七个月宝宝晚上咳嗽厉害怎么办 孕7个月感冒咳嗽怎么办 4个月婴儿肺炎怎么办 宝宝吃胡萝卜泥拉肚子怎么办 宝宝吃土豆泥不消化怎么办 五个月宝宝奶睡怎么办 橘子和牛奶一起吃了怎么办 半岁宝宝不喝水怎么办 一岁宝宝总是便秘怎么办 1岁的宝宝不喝水怎么办 两月宝宝不喝水怎么办 破壁机打出的果汁很浓稠怎么办 榨的果汁不甜怎么办 11个月宝宝吃盐怎么办 1岁半宝宝长牙慢怎么办