Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 实模式程序集:在引导时将字符打印到屏幕而不使用INT指令_Assembly_Bootloader_Bios - Fatal编程技术网

Assembly 实模式程序集:在引导时将字符打印到屏幕而不使用INT指令

Assembly 实模式程序集:在引导时将字符打印到屏幕而不使用INT指令,assembly,bootloader,bios,Assembly,Bootloader,Bios,以下站点提供了一个代码示例,在系统启动时将“a”打印到屏幕上。从我读到的内容来看,你不需要使用INT操作码来让BIOS做某些事情吗?下面的代码是如何在不使用中断的情况下工作的?代码的哪一部分实际告诉硬件在屏幕上打印“A” 有关守则: .code16 .section .text .globl _start _start: mov $0xb800, %ax mov %ax, %ds movb $'A', 0 movb $0x1e, 1 idle: jmp idle 附加到

以下站点提供了一个代码示例,在系统启动时将“a”打印到屏幕上。从我读到的内容来看,你不需要使用INT操作码来让BIOS做某些事情吗?下面的代码是如何在不使用中断的情况下工作的?代码的哪一部分实际告诉硬件在屏幕上打印“A”

有关守则:

.code16
.section .text
.globl _start
_start:
  mov $0xb800, %ax
  mov %ax, %ds
  movb $'A', 0
  movb $0x1e, 1
idle:
  jmp idle 

附加到原始问题之后

如果我使用以下代码,BIOS调用是否为我写入文本缓冲区?从地址0xb800开始的缓冲区

   # Author: Matthew Hoggan
   # Date Created: Tuesday, Mar 6, 2012
   .code16                        # Tell assembler to work in 16 bit mode (directive)
   .section .text
   .globl _start                  # Help linker find start of program
   _start:
       movb $0x0e,     %ah        # Function to print a character to the screen                 
       movb $0x00,     %bh        # Indicate the page number
       movb $0x07,     %bl        # Text attribute
       mov  $'A',      %al        # Move data into low nibble                   
       int  $0x10                 # Video Service Request to Bios                             
   _hang:                         
       jmp  _hang                 
       .end   

启动时,您处于默认屏幕模式—在本例中为文本屏幕模式。您的示例程序直接写入文本屏幕模式下屏幕上显示的字符缓冲区。将数据段寄存器设置为
0xb800
,就是将事情设置为指向该缓冲区。查看了解更多信息。

直接回答您的问题:行“movb$'A',0”有效地完成了屏幕打印(下面的行“movb$0x1e,1”指定了它应该是什么颜色)

详细回答:视频硬件根据内存内容绘制屏幕。在文本模式下,视频硬件开始基于内存段0xB800绘制。字节0处的内容定义了要在屏幕上第一个文本单元格中绘制的字符。下一个字节定义属性(前景色、背景色和闪烁状态)。此模式在整个屏幕中重复(char-attr-char-attr)


所以,从技术上讲,我的直接回答不是真的。两个“movb”语句只是将字母“A”分阶段打印出来直到下一次硬件根据内存刷新显示时,才会打印“A”。

基本上,当您调用INT 10h时,BIOS将执行一个例程,通过将字符及其属性写入视频内存来执行几乎相同的操作。然而,知道如何自己编写和执行这些例程是很有用的,因此,当您决定将CPU切换到32位保护模式时,您仍然可以在屏幕上打印字符,因为在该模式下,您将无法再调用BIOS中断。

在您发送给我的链接中,他使用的是INT。在上面的代码中,mov 0xb800到ax设置指向缓冲区的指针?为什么他有两条mov线路?为什么不只是mov$0xb800,%ds?。另一个问题是mov$'A',0实现了什么?它是否将“A”移动到相对地址“0”?还有movb$0x1e,1是否将属性移动到相对地址1?我仍然有点困惑。对不起-我只是想链接是对数据段部分的解释。您不能将常数直接移动到
ds
,这就是为什么这是一个两步过程。您的示例程序将数据段设置为
0xb800
,然后在
0xb800:0000
中放置ASCII
'A'
,在
0xb800:0001
中放置文字
0x1e
@多媒体迈克的回答是一个很好的解释,我认为。这是我的一个附带项目,我希望你不要介意所有的问题。非常感谢你的帮助。在上面,我把我的原始问题附加在后面,以便更好地理解正在发生的事情。你能再详细解释一下吗?恐怕我对这类东西了解不够;你可能想看看我答案中的链接。我认为那个家伙在谈论同样的事情。两个问题,硬件会以自己的刷新率刷新吗?这是基于CPU周期吗?如果我想更多地了解这方面,你有什么好的参考资料吗?是的,硬件有自己的功能。当我想到这些文本模式时,我想到的是30年前的MS-DOS。当时监视器以50或60 Hz的频率运行(分别为PAL或NTSC)。那就是每秒刷新50或60次。大多数视频硬件允许软件轮询一点,以了解是否发生垂直刷新。这对于防止图形闪烁很有用,但对于文本模式来说通常不是什么大问题。至于参考文献,我想维基百科关于文本模式的文章将是一个良好的开端:确实如此。不过,缓冲区的位置实际上取决于图形芯片。在单色适配器上,您将使用段0xb000而不是0xb800。