Why is My printing in assembly not printing characters after the 26th line?

空扰寡人 提交于 2019-12-11 05:25:40

问题


I'm pretty much learning Assembly and succeeded in working out my problem in printing here

Now I have another question.

I'm using emu8086. I have this code print an image of a minion in bits using the space character with background color. I managed to make it print the image per line but when it reached the 26th line, it stopped printing and there is this error of "wrong interrupt".

Can anyone help me.

Here is the entire code:

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

回答1:


Given the use of 0B800h as the video segment and the use of EMU8086, it's clear that you're working on the 80x25 text screen. The video RAM behind this screen occupies a total of 4000 bytes. When your program addresses a location below this area (using mov di,4172 and mov di,4188) it effectively writes off-screen.

If you were running this code in a true BIOS/DOS environment then these off-screen writes would just go in the extra display pages, but since this is EMU8086 those extra display pages don't exist. So you should never write outside of these 4000 bytes.


As @Ruud said you forgot to specify the function code in the AH register for the SetCursor function.

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

;line 26 Hand, Body blue

Since you named the first line of the screen line 1, the line that you're (trying to) writing to below this comment is rather 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

Why do you repeat these instructions so many times? Once you've set the ES segment register to the correct value, it remains set for more than a single output.




回答2:


The major problem is missing ah value for the last int 10h. At that point the ah is 0xE8 (attribute from hand/body blue), and int 10h doesn't have such function.

Also clean up your notation a bit, when describing problems, etc. Think for a while about the numbers you are using, let me try to summarize:

Used text mode has resolution 80x25 characters (you can also try to select other modes, VGA has several of them).

Address of character is (y * 80 + x) * 2, where y is [0,24] and x is [0,79]. Note how the maximum valid value for x/y is "size-1", not size itself. So already y = 25 would put you off the visible area of screen.

From this I would expect you to use "line 0" to "line 24", not "line 1"->"line 25", as it is using directly the y value for line description.

But writing into off-screen area is normally a valid operation on VGA IBM PC, and actually you may tamper (at least on real HW, not sure about emu8086) with registers of VGA card to move the start of video memory from B800:0000 further away, creating "fast scrolling" without rewriting the video memory content for each char. It just doesn't make sense in your example as you don't scroll the screen (and from the problems you have I would say a direct modification of VGA control registers is a bit advanced topic for you at the moment).


There are many redundancies in your code, the setup of es is just one of them (as Fifoernik noted).

Also things like mov di,396;<target_address = y*160 + x*2> ; es:di set up IMO are complicating it for you without any benefit.

I can't try emu8086 myself, but I would be very surprised if mov di,2*160 + 38*2 would not compile, which will allow you to keep "[x,y]" visible for human reading the source (of course in disassembly there will be only resulting 396 value, which is compiled into outputted machine code).

(I would be surprised up to a point to suggest you to ditch emu8086 and use NASM + dosbox + some DOS debugger, that one also emulates VGA in very decent manner, including many control registers, so if you ever want to relive old era of setting graphic card directly, most of the VGA stuff should work with dosbox, if not all)

And for example after mov di,390 ... stosw in next code you do mov di,392, while the di already is 392 (you even have that in comment after stosw instruction). You can "chain" those stosw operations interleaved only with changing ah and/or al as needed, for writing consecutive characters on single line.

Maybe you should stop for a while with creating the ASCII art, and step over your code in debugger few times, plus watch how registers change, and try to better understand how CPU works, it will save you some time later, as you will be able to write shorter code (but try to keep it readable).



来源:https://stackoverflow.com/questions/40150627/why-is-my-printing-in-assembly-not-printing-characters-after-the-26th-line

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!