我需要使用中断10h的函数06h来实现滚动行。问题是我有滚动的行,但符号没有显示,光标消失,没有任何事情发生。也许我忘记了要考虑的事情?要编写代码,我使用FASM
。代码是引导加载程序的一部分。这是与滚动相关的代码:
cmp cx, 2001
je ScrollLine
我有一个计数器,当它达到2001(从1开始计数)时,控制传递给ScrollLine。
ScrollLine:
mov ah, 06h
mov al, 1
mov bh, 07
mov cx, 0000h
mov dx, 184Fh
int 10h
ret
我的完整引导加载程序代码如下:
use16
org 7C00h
start:
mov ah, 00h
mov al, 02h
int 10h
mov ax, NewInt40
call ChangeIVT
mov cx, 0
wait_loop:
xor ax, ax
inc cx
cmp cx, 2001
je ScrollLine
mov ah, 0
int 16h
push ax
call PrintChar
jmp wait_loop
NewInt40:
sti
push ax
mov ax, msg
cmp bl, 3
je PrintChar
cmp bl, 2
je PrintString
cmp bl, 1
je Clear
cmp bl, 4
je Scroll
pop ax
iret
ChangeIVT:
push bx
xor bx, bx
mov es, bx
mov bx, 40h
shl bx, 2
mov word [es:bx], ax
mov word [es:bx+2], 0
pop bx
ret
PrintString:
push si
push bx
push es
mov si, ax
mov ax, 0B800h
mov es, ax
xor bx, bx
xor dx, dx
@@:
lodsb
cmp al, 0
je @f
mov byte [es:bx], al
mov byte [es:bx+1], 1Eh
mov ah, 0Eh
add bx, 2
inc dx
mov ah,02h
mov al,02h
int 10h
jmp @b
@@:
pop es
pop bx
pop si
ret
PrintChar:
push bp
mov bp, sp
push bx
push es
push cx
mov ax, 0B800h
mov es, ax
xor bx, bx
xor dx, dx
mov ah,3
int 0x10
movzx ax, dh
movzx bx, dl
mov cx, 80
push dx
mul cx
pop dx
add bx, ax ; bx = 80 * dh + dl
shl bx, 1 ; bx = 2 * (80 * dh + dl)
mov ax, [bp + 4]
mov byte [es:bx], al
mov byte [es:bx+1], 1Eh
cmp dl, 79
jl @f
inc dh
mov dl, -1
@@:
inc dl
pop cx
mov bh, 0
mov ah, 2
int 0x10
pop es
pop bx
mov sp, bp
pop bp
ret
Clear:
mov AH,0
mov AL,2
int 10H
ret
Scroll:
mov ah, 06h
mov al, 1
mov bh, 07
mov cx, 0000h
mov dx, 184Fh
int 10h
ret
ScrollLine:
mov bl, 4
int 40h
xor cx, cx
ret
msg db "Hello, world!", 0Dh, 0Ah, 0
db 510-($-$$) dup (0)
db 55h, 0AAh
答案 0 :(得分:1)
您正在使用跳转进行呼叫。
在NewInt40
ISR中,您有条件地跳转到子例程PrintString
,PrintChar
,Scroll
等,但是从ret
返回。< / p>
我不知道代码是如何构建的,所以我只提出了使其工作所需的最小更改,没有什么可以被称为良好实践。
由于您正在编写引导加载程序,因此您现在肯定知道要修复的内容。
NewInt40:
sti
push ax
push bp ;; Save caller's BP
mov bp, sp ;; Save SP, so we can restore the stack pointer
push WORD _ni40_end ;; Push return address of every routine
mov ax, msg
cmp bl, 3
je PrintChar
cmp bl, 2
je PrintString
cmp bl, 1
je Clear
cmp bl, 4
je Scroll
_ni40_end: ;; NASM label
mov sp, bp ;; Restore stack pointer (in any case)
pop bp ;; Restore caller BP
pop ax
iret
抱歉,我为 NASM 撰写文章,但很容易转换为 FASM 。
P.S。
当您的引导加载程序“变得疯狂”,例如没有响应或单独行动时,很可能是您“失去了执行流程”的症状。
这意味着您正在执行不是您的代码的字节,并且当您使用不平衡堆栈返回时会发生这种情况
如果再次出现类似情况,请仔细检查您的退货。