第1章 打印启动信息

显示器I/O知识

显存地址是 0xb8000,屏幕是80*25,每个位置由两个字节决定。第一个字节决定所显示的字符,如0xb8000。第二个字节决定怎么显示字符(背景颜色,前景颜色),如0xb8001。

汇编命令知识

cld: 方向标志置0,si和di 增1或增2;
std: 方向标志置1,si和di 减1或减2

串传送指令(数据从A内存到B内存)

cld
movsb   # ds:[si] -> es:[di], ++si, ++di 
movsw   # ds:[si] -> es:[di], si+=2, di+=2

串存储指令(数据从寄存器到内存)

cld
stosb  # al -> es:[di], ++si
stosw  # ax ->es:[di], si+=2

串读取指令(数据从内存到寄存器)

cld
lodsb # ds:[si] –> al, ++si
lodsw # ds:[si] –> ax, si+=2

重复前缀指令

rep: 用在movs、stos、lods指令前,每执行一次指令,cx减1;直到cx = 0,重复执行结束。

下面这段代码的作用是把内存中的字符串复制到0xb8000地址上

.text
    .global start
    .code16
start:
    jmp $0x0, $code
msg:
    .string "1kos booting......\x0"
code:
    movw    $0xb800,%ax        #显存地址在0xb8000
    movw    %ax,    %es        
    xorw    %di,    %di        #es:di = 0xb8000
    xorw    %ax,    %ax
    movw    %ax,    %ds        #ds:si = msg
    movw    $msg,   %si
    cld                #si和di自增
    movb    $0x07,  %ah        #字符属性:黑底白字

loop:
    cmp        $0x0,   (%si)
    je        end
    lodsb            #ds:[si] -> al, ++si
    stosw            #ax -> es:[di], di += 2  #al=字符 ah=属性
    jmp        loop

end:
    jmp        end

Leave a Reply

Your email address will not be published. Required fields are marked *