Почему моя печать в сборке не печатает символы после 26-й строки?

Я в значительной степени изучаю Ассемблер и преуспел в решении моей проблемы с печатью здесь

Теперь у меня другой вопрос.

Я использую 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

person Myk Agustin    schedule 20.10.2016    source источник
comment
@Ped7g надеюсь, что вы тоже можете помочь здесь   -  person Myk Agustin    schedule 20.10.2016
comment
Исторически сложилось так, что текстовый режим на ПК ограничен 25 строками. Строка 26 (частично) находится за пределами диапазона памяти вашей видеопамяти. Emu8086 может счесть это segfault. Кстати, ближе к концу вы вызываете INT 10h, не устанавливая сначала AH в 2.   -  person Ruud Helderman    schedule 20.10.2016
comment
Что такое строка 26 в 80x25? Может быть, вы хотите сначала переключиться в какой-нибудь другой текстовый режим с большим количеством строк? Типа 80х50? en.wikipedia.org/wiki/ ... в формате 80x25 26-я строка не существует, поэтому я не уверен, чего вы хотите достичь.   -  person Ped7g    schedule 20.10.2016
comment
@Ped7g Ped7g, можно ли переключить его на больший экран, я пытался изменить размер экрана перед запуском кода ... все та же проблема, даже если размер экрана сверху говорит [80 x 50 символов]   -  person Myk Agustin    schedule 21.10.2016
comment
Я не понимаю, что ты пытался. Изменить размер экрана? Вы имеете в виду изменение графического режима? Какая такая же проблема? Вы сначала исправили этот int 10h в конце кода? (см. комментарий Рууда) После этого ваша оригинальная версия должна работать (не видны только нижние строки, так как они находятся за пределами экрана), так ли это?   -  person Ped7g    schedule 21.10.2016


Ответы (2)


Учитывая использование 0B800h в качестве сегмента видео и использование EMU8086, становится ясно, что вы работаете с текстовым экраном 80x25. Видеопамять за этим экраном занимает всего 4000 байт. Когда ваша программа обращается к расположению ниже этой области (используя mov di,4172 и mov 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 на правильное значение, он останется установленным более чем для одного выхода.

person Fifoernik    schedule 20.10.2016

Основная проблема заключается в отсутствии значения ah для последнего int 10h. В этот момент ah становится 0xE8 (атрибут руки/тела синий), а int 10h не имеет такой функции.

Также немного очистите свои обозначения при описании проблем и т. Д. Подумайте немного о числах, которые вы используете, позвольте мне попытаться обобщить:

Используемый текстовый режим имеет разрешение 80х25 символов (можно попробовать выбрать и другие режимы, у VGA их несколько).

Адрес символа — (y * 80 + x) * 2, где y — [0,24], а x — [0,79]. Обратите внимание, что максимальным допустимым значением для x/y является «size-1», а не сам размер. Так что уже y = 25 выведет вас за пределы видимой области экрана.

Исходя из этого, я ожидаю, что вы будете использовать «строку 0» до «строки 24», а не «строку 1» -> «строку 25», поскольку она использует непосредственно значение y для описания строки.

Но запись в область за пределами экрана обычно является допустимой операцией на VGA IBM PC, и на самом деле вы можете подделать (по крайней мере, на реальном HW, не уверен насчет emu8086) регистры VGA-карты, чтобы переместить начало видеопамяти с B800:0000. дальше, создавая «быструю прокрутку» без перезаписи содержимого видеопамяти для каждого символа. Это просто не имеет смысла в вашем примере, поскольку вы не прокручиваете экран (и из ваших проблем я бы сказал, что прямая модификация регистров управления VGA на данный момент является для вас немного сложной темой).


В вашем коде много избыточности, настройка es — лишь одна из них (как заметил Fifoernik).

Кроме того, такие вещи, как mov di,396;<target_address = y*160 + x*2> ; es:di set up IMO, усложняют вам это без какой-либо пользы.

Я не могу попробовать 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-арта и несколько раз просмотреть свой код в отладчике, а также посмотреть, как меняются регистры, и попытаться лучше понять, как работает процессор, это сэкономит вам время позже, так как вы будете может писать более короткий код (но старайтесь, чтобы он был читабельным).

person Ped7g    schedule 20.10.2016