显示字符串

字符串中断

通过AH=13H中断来显示字符串。

BIOS中断定义如下

入口参数:

AH=13H //在Teletype模式下显示字符串

BH=页码

BL=属性。背景色和文字颜色(若AL=00H或01H)

CX=显示字符串长度

(DH、DL)=坐标(行、列)

ES:BP=显示字符串的地址 AL=显示输出方式

0--字符串中只含显示字符,其显示属性在BL中。显示后,光标位置不变

1--字符串中只含显示字符,其显示属性在BL中。显示后,光标位置改变

2--字符串中含显示字符和显示属性。显示后,光标位置不变

3--字符串中含显示字符和显示属性。显示后,光标位置改变

显示字符串函数

我们设置字符串遇到0表示结束,然后将读取的内容调用BIOS中断进行显示。

此处使用汇编定义了一个显示字符串的函数。然后进行调用。

函数如下:

; ------------------------------------------------------------------------
; 显示字符串函数:PutString
; 参数:
; si = 字符串开始地址,
; dh = 第N行,0开始
; dl = 第N列,0开始
; ------------------------------------------------------------------------
PutString:
            mov cx,0            ;BIOS中断参数:显示字符串长度
            mov bx,si
    .s1:;获取字符串长度
            mov al,[bx]         ;读取1个字节到al
            add bx,1            ;读取下个字节
            cmp al,0            ;是否以0结束
            je .s2
            add cx,1            ;计数器
            jmp .s1
    .s2:;显示字符串
            mov bx,si
            mov bp,bx
            mov ax,ds
            mov es,ax           ;BIOS中断参数:计算[ES:BP]为显示字符串开始地址

            mov ah,0x13         ;BIOS中断参数:显示文字串
            mov al,0x01         ;BIOS中断参数:文本输出方式(40×25 16色 文本)
            mov bh,0x0          ;BIOS中断参数:指定分页为0
            mov bl,0x1F         ;BIOS中断参数:指定白色文字            
            mov dl,0            ;列号为0
            int 0x10            ;调用BIOS中断操作显卡。输出字符串
            ret

程序代码

内容如下

;Rats OS
;TAB=4
[bits 16]
    org     0x7c00          ;指明程序的偏移的基地址

;引导扇区代码  
    jmp     Entry
    db      0x90
    db      "RATSBOOT"      ;启动区的名称可以是任意的字符串(8字节)       

;程序核心内容
Entry:

    mov ah,0x06             ;清除屏幕                   
    mov al,0
    mov cx,0   
    mov dx,0xffff  
    mov bh,0x17             ;属性为蓝底白字
    int 0x10
    

    mov ah,0x02             ;光标位置初始化
    mov dx,0
    mov bh,0
    mov dh,0x0
    mov dl,0x0
    int 0x10

    ;---------------------------
    ;输出字符串
    mov si,HelloMsg         ;将HelloMsg的地址放入si
    mov dh,0                ;设置显示行
    mov dl,0                ;设置显示列
    call Func_Sprint        ;调用函数

    
    jmp $                   ;进入死循环,不再往下执行。


; ------------------------------------------------------------------------
; 显示字符串函数:Func_Sprint
; 参数:
; si = 字符串开始地址,
; dh = 第N行,0开始
; dl = 第N列,0开始
; ------------------------------------------------------------------------
Func_Sprint:
            mov cx,0            ;BIOS中断参数:显示字符串长度
            mov bx,si
    .len:;获取字符串长度
            mov al,[bx]         ;读取1个字节到al
            add bx,1            ;读取下个字节
            cmp al,0            ;是否以0结束
            je .sprint
            inc cx              ;计数器
            jmp .len
    .sprint:;显示字符串
            mov bx,si
            mov bp,bx
            mov bx,ds
            mov es,bx           ;BIOS中断参数:计算[ES:BP]为显示字符串开始地址

            mov ah,0x13         ;BIOS中断参数:中断模式
            mov al,0x01         ;BIOS中断参数:输出方式
            mov bh,0x0          ;BIOS中断参数:指定分页为0
            mov bl,0x1F         ;BIOS中断参数:显示属性,指定白色文字           
            int 0x10            ;调用BIOS中断操作显卡。输出字符串
            ret
; ------------------------------------------------------------------------
;准备显示字符串
HelloMsg: db "hello,ratsos!",0

FillSector:
    resb    510-($-$$)          ;处理当前行$至结束(1FE)的填充
    db      0x55, 0xaa

构建运行

Makefile文件

# tools
NASM=nasm
QEMU=qemu-system-x86_64

# args
boot=boot
build=build

target: prepare $(build)/ratsos.img
    $(QEMU) -m 128  -localtime -fda $(build)/ratsos.img

$(build)/ratsos.img:
    $(NASM) -f bin -o  $(build)/ratsos.img $(boot)/boot.asm

prepare:
    ifeq ($(build), $(wildcard $(build)))
        @echo "build directory exist..."
    else
        mkdir -p $(build)
    endif

clean:
    rm -rf $(build)/*

显示结果如下:

猜你喜欢

转载自www.cnblogs.com/mlzrq/p/10223039.html