【问题标题】:Why is My printing in assembly not printing characters after the 26th line?为什么我在汇编中的打印在第 26 行之后不打印字符?
【发布时间】:2016-10-20 09:32:48
【问题描述】:

我正在学习组装,并成功解决了打印here的问题

现在我还有一个问题。

我正在使用emu8086。我让这段代码使用带有背景颜色的空格字符以位打印小兵的图像。我设法让它每行打印图像,但是当它到达第 26 行时,它停止打印并且出现“错误中断”的错误。

谁能帮帮我。

完整代码如下:

org 100h

name "charchar"


org  100h

;buhok line 1   (Grey)
mov ax,0B800h
mov es,ax
mov di,56;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,179  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2  

;buhok line 2
mov ax,0B800h
mov es,ax
mov di,200;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,092  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2 

mov ax,0B800h
mov es,ax
mov di,202;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,092  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2

mov ax,0B800h
mov es,ax
mov di,208;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,179  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2

mov ax,0B800h
mov es,ax
mov di,210;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,179  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2  

mov ax,0B800h
mov es,ax
mov di,214;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,179  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2                                  

mov ax,0B800h
mov es,ax
mov di,216;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,179  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2    

mov ax,0B800h
mov es,ax
mov di,218;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,179  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2 

mov ax,0B800h
mov es,ax
mov di,222;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,179  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2    

mov ax,0B800h
mov es,ax
mov di,226;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,179  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2 

mov ax,0B800h
mov es,ax
mov di,230;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,047  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2 

mov ax,0B800h
mov es,ax
mov di,234;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,047  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2   

;buhok line 3
mov ax,0B800h
mov es,ax
mov di,352;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,092  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2

mov ax,0B800h
mov es,ax
mov di,354;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,092  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2

mov ax,0B800h
mov es,ax
mov di,356;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,092  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2

mov ax,0B800h
mov es,ax
mov di,358;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,092  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2

mov ax,0B800h
mov es,ax
mov di,360;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,092  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2  

mov ax,0B800h
mov es,ax
mov di,362;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,092  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2

mov ax,0B800h
mov es,ax
mov di,364;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,092  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2 

mov ax,0B800h
mov es,ax
mov di,366;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,092  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2

mov ax,0B800h
mov es,ax
mov di,368;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,179  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2 

mov ax,0B800h
mov es,ax
mov di,370;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,179  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2 

mov ax,0B800h
mov es,ax
mov di,372;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,179  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2 

mov ax,0B800h
mov es,ax
mov di,374;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,179  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2 

mov ax,0B800h
mov es,ax
mov di,376;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,179  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2 

mov ax,0B800h
mov es,ax
mov di,378;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,179  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2

mov ax,0B800h
mov es,ax
mov di,382;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,179  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2   

mov ax,0B800h
mov es,ax
mov di,384;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,179  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2

mov ax,0B800h
mov es,ax
mov di,386;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,179  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2

mov ax,0B800h
mov es,ax
mov di,388;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,47  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2  

mov ax,0B800h
mov es,ax
mov di,390;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,47  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2 

mov ax,0B800h
mov es,ax
mov di,392;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,47  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2

mov ax,0B800h
mov es,ax
mov di,394;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,47  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2

mov ax,0B800h
mov es,ax
mov di,396;<target_address = y*160 + x*2>  ; es:di set up
mov ah,00001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,47  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2

........

;line 26 Hand, Body blue

mov ax,0B800h
mov es,ax
mov di,4172;<target_address = y*160 + x*2>  ; es:di set up
mov ah,10001000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,' '  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2
mov al,' '  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2 
mov al,' '  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2
mov al,' '  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2

mov ax,0B800h
mov es,ax
mov di,4188;<target_address = y*160 + x*2>  ; es:di set up
mov ah,11101000b;<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,' '  ; al = letter, ah = attribute (ax set up)
stosw       ; [es:di] = ax, di += 2 



  mov  dl,0 ;X (SCREEN COORDINATE). 
  mov  dh,5 ;Y (SCREEN COORDINATE). 
  int  10h ;BIOS SCREEN SERVICES.  

;FINISH THE PROGRAM PROPERLY.
  mov  ax,4c00h
  int  21h

ret

【问题讨论】:

  • @Ped7g 希望你也能在这里帮忙
  • 从历史上看,PC 上的文本模式限制为 25 行。第 26 行(部分)超出了您的视频 RAM 内存范围。 Emu8086 可能认为这是一个段错误。顺便说一句,在接近尾声时,您无需先将 AH 设置为 2,而是调用 INT 10h
  • 80x25 中的第 26 行是什么?也许您想先切换到其他文本模式更多行?喜欢 80x50? en.wikipedia.org/wiki/… ... 在 80x25 中,“第 26 行”不存在,所以我不确定你想要实现什么。
  • @Ped7g 是否可以将其切换到“更大”的屏幕我尝试在运行代码之前调整屏幕尺寸.. 即使屏幕尺寸显示为 [80 x 50,仍然存在同样的问题字符]
  • 我不明白你的尝试。调整屏幕大小?你的意思是改变图形模式?什么是“同样的问题”?您是否首先在代码末尾修复了 int 10h ? (请参阅 Ruud 的评论)之后您的原始版本应该可以工作(只有底线不可见,因为它们在屏幕外区域),是这样吗?

标签: assembly emu8086


【解决方案1】:

鉴于使用 0B800h 作为视频片段和使用 EMU8086,很明显您正在使用 80x25 文本屏幕。这个屏幕后面的视频RAM总共占用了4000字节。当您的程序寻址该区域下方的位置时(使用mov di,4172mov di,4188),它有效地在屏幕外写入。

如果您在真正的 BIOS/DOS 环境中运行此代码,那么这些屏幕外写入只会进入额外的显示页面,但由于这是 EMU8086,因此这些额外的显示页面不存在。所以你永远不应该在这 4000 字节之外写。


正如@Ruud 所说,您忘记在 AH 寄存器中为 SetCursor 函数指定函数代码。

mov  dl, 0 ;X (SCREEN COORDINATE). 
mov  dh, 5 ;Y (SCREEN COORDINATE). 
mov  ah, 2
int  10h   ;BIOS SetCursor.

;line 26 Hand, Body blue

由于您将屏幕的第一行命名为 line 1,因此您正在(试图)在此评论下方写入的行是 line 27

3840 -> 3999 line 25
4000 -> 4159 line 26
4160 -> 4319 line 27    <-- 4172 and 4188 belong here!

mov ax,0B800h
mov es,ax

你为什么重复这些指令这么多次?将 ES 段寄存器设置为正确的值后,它会保持设置为多个输出。

【讨论】:

    【解决方案2】:

    主要问题是缺少最后一个int 10hah 值。此时ah0xE8(来自手/身体蓝色的属性),而int 10h 没有这样的功能。

    还要清理一下你的符号,在描述问题时等等。想一想你正在使用的数字,让我试着总结一下:

    使用的文本模式分辨率为 80x25 字符(您也可以尝试选择其他模式,VGA 有几种)。

    字符地址是(y * 80 + x) * 2,其中y 是[0,24],x 是[0,79]。请注意 x/y 的最大有效值是“size-1”,而不是 size 本身。所以y = 25 已经让你远离屏幕的可见区域了。

    因此,我希望您使用“第 0 行”到“第 24 行”,而不是“第 1 行”->“第 25 行”,因为它直接使用 y 值作为行描述。

    但是在 VGA IBM PC 上写入屏幕外区域通常是有效的操作,实际上您可能会篡改(至少在真实硬件上,不确定 emu8086)与 VGA 卡的寄存器以移动视频内存的开头B800:0000 更远,创建“快速滚动”而不重写每个字符的视频内存内容。这在您的示例中没有意义,因为您不滚动屏幕(从您遇到的问题来看,我想说直接修改 VGA 控制寄存器目前对您来说是一个有点高级的话题)。


    您的代码中有很多冗余,es 的设置只是其中之一(正如 Fifoernik 所说)。

    mov di,396;&lt;target_address = y*160 + x*2&gt; ; es:di set upIMO 之类的东西也会让你复杂化,但没有任何好处。

    我自己无法尝试emu8086,但如果mov di,2*160 + 38*2 无法编译,我会感到非常惊讶,这将允许您保持“[x,y]”对人类阅读源代码可见(当然在那里进行反汇编)只会得到 396 值,编译成输出的机器码)。

    (我会惊讶地建议你放弃 emu8086 并使用 NASM + dosbox + 一些 DOS 调试器,它还以非常体面的方式模拟 VGA,包括许多控制寄存器,所以如果你想重温直接设置显卡的旧时代,大多数VGA东西都应该与dosbox一起使用,如果不是全部)

    例如,在下一个代码中的mov di,390 ... stosw 之后,您执行mov di,392,而di 已经是392(您甚至在stosw 指令之后的注释中也有这个)。您可以“链接”那些 stosw 操作交错,仅根据需要更改 ah 和/或 al,以便在单行上写入连续字符。

    也许你应该停下来创建 ASCII 艺术,在调试器中跳过你的代码几次,观察寄存器如何变化,并尝试更好地理解 CPU 是如何工作的,它会在以后为你节省一些时间,因为您将能够编写更短的代码(但尽量保持可读性)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-30
      • 1970-01-01
      • 2013-12-20
      • 2013-06-27
      • 2020-03-11
      • 1970-01-01
      • 2020-07-20
      • 2020-07-05
      相关资源
      最近更新 更多