【完整代码已经归档到 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环境下通过汇编语言编写print_hex和print_string两个函数,分别用于以十六进制打印bx寄存器内容和打印bx寄存器指向的字符串。代码已上传至GitHub仓库mini_bootloader。
42

被折叠的 条评论
为什么被折叠?



