美文网首页技术干货码农の日常汇编语言
开发OS二日目之必要汇编指令

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

作者: TaXue_WWL | 来源:发表于2014-12-07 20:49 被阅读232次
    2e2eb9389b504fc2e40ad6e0e4dde71191ef6df9.jpg

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

    之所以在这里介绍几个汇编指令是因为,在开发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语言,看起来也不会很吃力,不过必要的时候还是要用汇编这张“王牌”,哈哈那么,这次的文章就告一段落了,有些地方说的不对的,还请大家提出意见和建议,现行谢过了

    相关文章

      网友评论

        本文标题:开发OS二日目之必要汇编指令

        本文链接:https://www.haomeiwen.com/subject/ryhntttx.html