【发布时间】:2012-11-06 05:52:52
【问题描述】:
我正在尝试编写一些 ASM 代码,这些代码将使用 BIOS 中断将一些文本写入显示器。此代码将从引导扇区运行。
我有
msgText DB "Hello" ;Text
msgCol DB 0x07,0x08,0x09,0x0A,0x0B ;Colours
msgXY DW 0x0E26 ;Col/Row
msgLen DB 0x05 ;Length
消息只是“你好”,每个字母都有不同的颜色。消息在屏幕上的位置大致在中间,长度为5。
我想编写一个函数,将任何消息/颜色/xy/长度写入屏幕,但现在,让我们专注于这个。
print:
MOV AH,0x02 ;Tell BIOS we want to set the cursor position
MOV DX,[msgXY] ;Tell BIOS where the cursor should go
INT 0x10 ;Call BIOS video interrupt
XOR ECX,ECX ;Clear ECX
MOV CX,[msgLen] ;Set CX = msgLen
MOV AH,0x0E ;We want to print characters on the screen
_loop:
MOV EDX,msgText ;Move address of text to EDX
DEC ECX ;Temporarily decrement ECX
ADD EDX,ECX ;Add ECX to the address of msgText
INC ECX ;Increment ECX back to what it was
MOV AL,BYTE[EDX] ;Put the contents of the memory at EDX into AL
MOV EDX,msgCol ;Move address of text colour to EDX
DEC ECX ;Temporarily decrement ECX
ADD EDX,ECX ;Add ECX to the address of msgCol
INC ECX ;Increment ECX back to what it was
MOV BL,BYTE[EDX] ;Put the contents of the memory at EDX into BL
INT 0x10 ;Call BIOS video interrupt
LOOP _loop
RET
现在,我应该可以用CALL print 调用它了。
(是的,我知道这会向后打印“Hello”,我并不担心。我可以将它作为“olleH”存储在内存中,我不在乎 - 我有更大的问题)
首先,我将CX 设置为[msgLen] 的行会导致问题。我不得不对其进行硬编码以使CX 等于0x05,但我不知道为什么。
其次,大概是出于同样的原因,当我尝试设置颜色代码时,我遇到了与文本长度相同的问题。如果我摆脱这些行并只硬编码MOV BL,0x0C,那么它工作正常。
不过,奇怪的是,MOV DX,[msgXY] 部分似乎工作正常。
我不能给出任何确切的问题,因为我已经尝试通过改变很多东西来解决这个问题几个小时,而我在这里和那里改变的小东西似乎会产生非常不可预测的结果。此外,调用各种 BIOS 中断似乎会更改某些寄存器,这很烦人。另外,当我将东西压入堆栈并稍后将其弹出时,情况有所不同,因此我一直避免使用PUSH 和POP。
顺便说一句,我现阶段仍处于实模式 x86。
当然,我正在做的事情不可能这么难。也许我只是需要一杯咖啡。或者一些帮助? :)
【问题讨论】:
标签: assembly nasm bootloader bios