1

我几乎在学习组装,并成功解决了我在这里打印的问题

现在我有另一个问题。

我正在使用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
4

2 回答 2

3

鉴于使用 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

由于您将屏幕的第一行命名为第1行,因此您(尝试)在此评论下方写入的行是第 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 段寄存器设置为正确的值,它就会保持设置为多个输出。

于 2016-10-20T10:30:10.643 回答
1

主要问题是 last 的缺失ahint 10h。那时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;<target_address = y*160 + x*2> ; 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交错的操作,以便在单行上写入连续字符。ahal

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

于 2016-10-20T12:37:56.620 回答