开发OS二日目之必要汇编指令

一看到题目写着 汇编二字,是不是心里一瞬间就产生畏惧感了呢(笑),其实汇编没有想得那么可怕的,我第一次接触汇编的时候因为不得法,也是感到头昏脑涨,被一堆寄存器搞得晕晕乎乎,现在回头再看,发现其实理清楚逻辑,它并没有那么可怕。

之所以在这里介绍几个汇编指令是因为,在开发OS的过程中,如果一直用二进制编码去写程序是一件让人很难受的事情,而借助汇编,可以极大的缩短代码量,更好的理清思维。 在第一篇文章中我们用二进制编辑器写出了一个简单的开机引导,在这一篇文章中我们用汇编语言对其进行改写,不要这么快就畏惧哦~相信看完本文,大家对汇编会有一个新的认识, “哦,其实汇编并不是很可怕嘛~”

首先看一下改写之后的代码

汇编代码表示

; hello-os
; TAB=4

        ORG     0x7c00          
        JMP     entry
        DB      0x90
        DB      "HELLOIPL"      
        DW      512           
        DB      1            
        DW      1              
        DB      2               
        DW      224           
        DW      2880            
        DB      0xf0            
        DW      9                
        DW      18          
        DW      2             
        DD      0               
        DD      2880         
        DB      0,0,0x29      
        DD      0xffffffff     
        DB      "HELLO-OS   "   
        DB      "FAT12   "      
        RESB    18              
entry:
        MOV     AX,0          
        MOV     SP,0x7c00
        MOV     DS,AX
        MOV     ES,AX
        MOV     SI,msg
putloop:
        MOV     AL,[SI]
        ADD     SI,1          
        CMP     AL,0
        JE      fin
        MOV     AH,0x0e        
        MOV     BX,15          
        INT     0x10          
        JMP     putloop
fin:
        HLT              
        JMP     fin          
msg:
        DB      0x0a, 0x0a     
        DB      "hello, world"
        DB      0x0a            
        DB      0
        RESB    0x7dfe-$       
        DB      0x55, 0xaa
        DB      0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
        RESB    4600
        DB      0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
        RESB    1469432

好吧,我承认这一堆看起来很难受,那么我们把它改写成C代码,这样开起来就会容易些

C代码表示

entry:
    AX = 0;
    SS = AX;
    SP = 0X7C00;
    DS = AX;
    ES = AX;
    SI = msg;
putloop:
    AL = BYTE[SI];
    SI = SI + 1;
    if(AL == 0)
    {
        goto fin;
    }
    AH = 0X0E;
    BX = 15;
    INT 0X10;
    goto putloop;
fin:
    HLT;
    goto fin; 

这样看起来好多了吧

不过好像那些奇怪的大写字符还是很多,别急,那些就是开头提到的寄存器了,接下来详细解释一下这些寄存器的功能和语句的含义。

详解汇编语句以及寄存器

  • DB指令:即data byte,它的含义是往文件中直接写入1个字节的指令
  • RESB指令:即reserve byte,从当前的地址开始空出N个字节, eg:RESB 10:从当前地址空出10个字节
  • DW:data word,代表8位(2字节)
  • DD:data doubleword,代表16位(4字节)
  • IPL:initial program loader,启动程序加载器

  • MOV指令:很常用的指令,功能非常简单,即赋值
    eg: MOV AX, 0 ;即AX = 0; MOV SS, AX ;即SS = AX; 还是很好理解吧~

    寄存器解释

    接下来就是重头戏了,也就是对几个重要的寄存器进行解释

  • AX(accumulator):累加寄存器(进行加法运算)
  • CX(counter):计数寄存器
  • DX(data):数据寄存器
  • BX(base):基址寄存器,(大家在数据结构应该接触过这个概念,就是地址的起始参照地址)
  • SP(stackpointer):栈指针寄存器
  • BP(basepointer):基址指针寄存器
  • SI(sourceindex):源变址寄存器
  • DI(destinationindex):目的变址寄存器 ps:上面所说的都是16位寄存器

下面的寄存器是8位寄存器,很简单是将上述的AX,CX,DX,BX分为高八位低八位

  • AH,CH,DH,BH:他们是上述的寄存器的高八位(high)
  • AL,CL,DL,BL:他们是上述的寄存器的低八位(low)
有心的同学们在这里也会会发问,

”既然有16位和8位寄存器,那么有没有32位的寄存器呢?” 当然是有的,因为我们用的不多,这里就不赘述了,感兴趣的可以去google一下,相信会有很多收获。

那我们继续,接下来说到的是段寄存器

  • ES(extra segment):附加段寄存器
  • CS(code segment):代码段寄存器
  • SS(stack segment):栈段寄存器
  • DS(data segment):数据段寄存器 他们的功能从名称上就可以反映出来

大家看下面这条语句

MOV AX [SI]

如果SI没有加“[]”,大家都能猜到他的作用是将SI中的数据赋值给AX,但此处加了括号,它的意思就变成将 SI的地址存储到AX中。 MOV指令有一个规则,即源数据和目的数据必须位数相同 所以上述语句就是讲SI地址的 一个字节给予AX。

  • ADD指令 顾名思义,进行加法运算,比如: >ADD SI, 1 ; SI = SI + 10:从当前地址空出10个字节
  • CMP指令 比较指令
  • JE指令 条件跳转指令,根据比较的结果决定跳转与否。JE即 jump if equal 与CMP结合使用,当比较的结果相等,则跳转到指定的地址;若比较结果不同,则不跳转,继续执行下一条指令。

看下面这段代码

CMP AL, 0
JE fin
其实等价于
if(AL == 0)
{
    goto fin;
}
  • INT指令 软件中断指令,(interrupt),INT后面是一个数字,使用不同的数字代表调用不同的函数,这些函数都是写在BIOS中的,方便程序员调用。

  • HLT指令 这条指令的目的是让CPU停止动作,但不是完全停止,那样的话就得断电。此处是指让CPU进入待机状态。 玩过linux的同学应该都用过“halt”这条指令进行关机操作吧。^_^

结语

这次介绍汇编还是比较吃力,毕竟自己明白一些和给别人讲解还是不一样的,不过大家放心啦,今后的开发会转到C语言,看起来也不会很吃力,不过必要的时候还是要用汇编这张“王牌”,哈哈~那么,这次的文章就告一段落了,有些地方说的不对的,还请大家提出意见和建议,现行谢过了~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值