我正在学习汇编,当然我正在尝试经典的 0x10 BIOS 中断。我查看的资源显示使用
lodsb
来打印字符串,因此为了理解该操作码,我试图模仿它的行为。这对于 lodsb
来说效果很好,但对于我所拥有的却不起作用。我做错了什么?:
开始: mov ah, 0Eh ;用于BIOS中断 mov si, text_string ;将源索引设置为text_string的开头 。重复: ;我试图模仿 lodsb 的行为来了解它是如何工作的: mov al, [si] ;将si处的字符放入al寄存器中 add si, 1 ;增加源索引 cmp al, 0 ;如果字符为零(字符串末尾) je done ;结束执行 int 10h ;BIOS 中断将字符显示在屏幕上 jmp.重复 text_string db '你好,世界!', 0 完毕: 雷特
通常不是一个好主意:
在第一个注释中,我会将
ah
设置为 0eh
之前的 int 10h
。
Int 10h/0eh
需要将 bh
和 bl
分别设置为页码和前景色。我也会在 int 10h
之前立即执行此操作,以确保它们已正确设置为通话。
顺便说一句,您可能需要确保
ds
段寄存器是正确的,例如:
push cs
pop ds
那是因为看起来您正在将字符串放入您的 code 段中。但是,由于
lodsb
版本显然可以工作,我假设您已经涵盖了(例如,如果此代码是 com
文件而不是 exe
文件)。
而且,从(诚然已经褪色的)记忆中,8086 有一个
inc si
指令,可以节省少量空间,这不再那么重要了,但我是在每个字节都很重要的时代被锻造的:-)
First lodsb 是一个命令,告诉计算机获取代码中的一个字符并增加偏移量。偏移量由[SI]决定,这是一个可以轻松设置的寄存器。一旦 SI 设置完毕,lodsb 就会获取 char 并将其放入 al 中。从此时起,阅读并确定要做什么。还有一个类似的问题这里。
使用 int 0x10 BIOS TTY 打印以零 (0x00) 结尾的字符串:
// print string terminated by zero
lea dx,welcome //<-pointer to string
loop:
mov bx,dx
mov al,byte ptr[bx]
cmp al,0
jz exit_loop
inc dx
mov ah,0x0e
mov bx,0x04
int 0x10
jmp loop
exit_loop: