linux的汇编学习(1)---实现打印寄存器的数值,或者打印字符串

【完整代码已经归档到    https://github.com/linzhanglong/mini_bootloader  】

这里实现了两个函数:

1.  一个是print_hex函数,用于实现把bx寄存器的内容以十六进制的形式显示出来
2.  一个是print_string函数,用于实现把bx寄存器所指向的字符串打印出来


直接看最终的代码实现:

[org 0x7c00]

;打印字符串
mov bx, hello_string
call print_string

;打印数字
mov bx, 0x1234
call print_hex

mov bx, 5555
call print_hex

jmp $

;把实现的两个打印函数的所在文件直接包含进来
%include "print.asm"

hello_string:
    db 'Hello', 0

times 510-($-$$) db 0
dw 0xaa55
    

对应输出的效果图:



print.asm文件实现的两个打印函数源码:

;该文件提供两个函数:
;   一个是print_hex函数,用于实现把bx寄存器的内容以十六进制的形式显示出来
;   一个是print_string函数,用于实现把bx寄存器所指向的字符串打印出来

;@ brief 先输出0x字符
init_print_hex:
    pusha
    mov ah, 0x0e
    
    mov al, '0'
    int 0x10   
    mov al, 'x'
    int 0x10     
    popa
    ret
;@ brief 输出完毕之后,加上回车
end_print_hex:
    pusha
    mov ah, 0x0e

    ;'\n'
    mov al, 0x0a 
    int 0x10
    mov al, 0x0d 
    int 0x10
    
    popa
    ret

;@ brief 把一个大小是0-15数字转为一位十六进制输出
;@ param bl保存要打印的数字[大小是0-15]
convert_one_hex:
    pusha
    mov ah, 0x0e

    ;如果数字大于15,异常。打印?号
    cmp bl, 15
    jg _ERROR

    ;如果数字大于10,那么转为A-F
    cmp bl, 10
    jge _LETTER

    ;如果数字是0-10,就只加上'0',就可以把0-10转为对应数字的ascii码
    add bl, '0'
    mov al, bl
    jmp _EXIT

_LETTER:
    ;先把数字减去10,然后加上A,就可以把10-15的数字转为A-F
    sub bl, 10
    add bl, 'A'
    mov al, bl
    jmp _EXIT
_ERROR:
    mov al, '?'
_EXIT:
    int 0x10
    popa
    ret

;@ brief 把一个数字转为多位十六进制输出
;@ param bx保存要打印的数字
print_hex:
    pusha
    call init_print_hex
    ;首先通过掩码和移位的方式,把数字以十六进制的方式从最后一位开始一个个压入堆栈
    ;然后输出时候才从堆栈里一个个取出来,这样就可以实现顺序打印
    xor cx, cx
_NEED_PUSH:
    ;取掩码获取数字以十六进制形式的最后一位,例如数字0x1234取出4,其中4保存到al,0x123保存到bx。cl计数
    mov ax, bx
    and ax, 0x0f
    shr bx, 4
    ;入栈并且计数
    push ax
    inc cl
    ;如果bx数值为0,表示我们已经全部处理完
    cmp bx, 0
    jne _NEED_PUSH
    
    ;开始出栈,并且显示
_NEED_POP:
    pop bx
    call convert_one_hex
    dec cl
    cmp cl, 0
    jne _NEED_POP
    
    call end_print_hex
    popa
    ret
    
;@ brief 打印字符串
;@ param bx要打印字符串的地址,字符串以0结尾
print_string:
    pusha
    mov ah, 0x0e
_NEXT_CHAR:
    mov al, [bx]
    cmp al ,0
    ;如果是0,表示字符串结尾了
    je _END
    ;显示一个字符
    int 0x10
    inc bx
    jmp _NEXT_CHAR
    
_END:
    ;回车
    mov al,  0x0a
    int 0x10
    mov al,  0x0d
    int 0x10

    popa
    ret
    
    
    


你可能感兴趣的:(linux的汇编学习(1)---实现打印寄存器的数值,或者打印字符串)