了解nasm程序集,用于在电传打字模式下输出字符

时间:2015-10-03 14:16:53

标签: nasm bootloader

我正在阅读关于操作系统编程的精彩内容

http://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev.pdf

在第12页上有一个简单的引导加载程序。

如果我理解相关内容,则显示的代码是您必须在NASM中编写的内容,以便让BIOS打印出字符。

我没有得到的是:

它说

we need interrupt 0x10 and to set ah to 0x0e (to indicate tele-type mode)
and al to the ASCII code of the character we wish to print.

但第一条指令是:

mov ah , 0x0e ;int 10/ ah = 0eh -> scrolling teletype BIOS routine

我不明白该行的评论。为什么第一行代码没有说:

mov ah, 0xeh
int 0x10

如果你需要做什么?

感谢您的帮助!

2 个答案:

答案 0 :(得分:3)

虽然Chrono给你一个答案,但我不太清楚它会回答你的问题。你似乎在问为什么评论说一件事而代码似乎做了另一件事。

基本前缀和后缀

几十年前,许多参考资料和一些反汇编程序使用了略微不同的默认表示法来表示十进制,十六进制,八进制和二进制基数,而不是今天看到的。他们将基数指定为值的最后一个字符(后缀)。常见的后缀是:

b = binary    10101010b      (decimal 170)    base 2
d = decimal   170d           (decimal 170) \  both d and t mean base 10 
t = decimal   170t           (decimal 170) /
h = hex       0AAh           (decimal 170)    base 16
o = octal     252o           (decimal 170)    base 8

如果数字不包含字母字符,则假定它是十进制的十进制数。所以这也适用:

no alphabetic character      170             decimal   170

大多数汇编程序将接受大多数这些后缀,但它们也将支持将base定义为前缀。如果值不以字母字符结尾但以0开头,后跟字母,则字母表示基数。常见的前缀基础是:

b = binary    0b10101010     (decimal 170)    base 2
d = decimal   0d170          (decimal 170) \  both d and t mean base 10 
t = decimal   0t170          (decimal 170) /
h = hex       0xAA           (decimal 170)    base 16
o = octal     0o252          (decimal 170)    base 8

大多数现代汇编程序都支持指定为前缀或后缀的表单。某些汇编程序可能不支持某些前缀和后缀,如t

如果指定带有前缀base的数字,则在整个文件中添加前缀。如果指定带后缀库的数字,则在整个文件中添加后缀。您可以将它们混合起来,但最好在文件中保持一致。

解释int 10 / ah = 0eh

这是什么意思:

int 10/ ah = 0eh -> scrolling teletype BIOS routine
  • int 10不包含字母,因此它是 decimal 10(或十六进制 a)。
  • 0eh以字母结尾,并且不以0和字母开头,因此h是后缀。 h表示十六进制。因此0eh十六进制 0e(或十进制 14)。

如果您将它放入BIOS的汇编程序代码中,它看起来像(使用十六进制后缀):

mov ah, 0eh      ; Decimal 14
int 0ah          ; Decimal 10. The 0 in front makes sure the assembler knows we don't mean register ah! 

使用前缀(本例中为十六进制):

mov ah, 0xe      ; Decimal 14
int 0xa          ; Decimal 10 

或者如果你想使用十进制(没有前缀或后缀):

mov ah, 14       ; Decimal 14
int 10           ; Decimal 10

但您现在可能会说嘿等等! 错误因为BIOS视频中断是0x10(或16十进制数)你是正确的!我们刚刚了解到评论错误或充其量非常含糊不清。评论应该说:

int 10h / ah = 0eh -> scrolling teletype BIOS routine

您可以与评论/代码的作者联系,让他们知道他们的评论不准确。他们写的代码是正确的。

如果汇编程序支持它们,我更喜欢0x0b0o之类的前缀,而不是后缀hbo因为某些后缀可能会形成寄存器名称或其他标识符和符号。使用后缀时,如果您的值必须以字母开头(即:以十六进制表示A到F),请在开头添加0,让汇编程序知道您正在表示值。例如,AAh必须写为0AAhBh必须写为0Bh

答案 1 :(得分:0)

注释仅用于上下文,指出AH=0x0e因为它表示在调用INT 0x10时滚动电传类型BIOS例程。

您可以将int XXX指令视为"执行函数XXX"出于简单目的的说明。在这种特殊情况下,如果您不首先使用您选择的字节加载AL寄存器,则每次INT 0x10出现时都会打印该寄存器中的任何字节。这就是AH最初为滚动电传打字例程加载0x0e的原因,然后每次都会加载AL并在之前显示字节执行INT 0x10指令。

在一些简单的评论伪代码中:

#AH=0x0e is the scrolling teletype BIOS routine when used with int 10h.
AH := 0x0e

#AL is the byte to display.
AL := 'H'

#Execute the scrolling teletype BIOS routine (AH=0x0e), displaying 'H' (AL='H').
INT 0x10