如何使用CMOVG指令从内存中的数据设置寄存器?

问题描述 投票:0回答:1

问题出在第 236 行的 Graphic 子例程内。(子标签 .writePixel 中的第 4、13 和 16 行)。
在此子例程中,我浏览从 280 到 487 列和 368 到 385 行的图形像素。 (像素面积为16x8)。
如果我找到黑色像素,那么我使用

cmovg
指令从垂直条纹的适当区域写入像素,并使用 BIOS 功能 0Ch 中断
int 10h

我对

cmovg

 指令的操作数有问题。我想将值从数据存储器(全局变量
barvy_kontrola)复制到AX寄存器(AH必须是0Ch,AL必须是图形像素的值)。

程序在第一次使用

cmovg

指令时崩溃。

这段代码:

pusha mov si, text_b call print_string_end2 popa
是测试块(在文本区域(80 x 25)的第23行和35列写入文本)

代码如下:

use16 org 0100h ; Return to main entry Main: ; Set video position and clear the screen automatically mov ah, 00h ;Invoked with: AH = 00h mov al, 03h ;text video mode (CGA 80 x 25) int 10h ; background draw mov ah, 09h mov al, 20h ; ASCII char 20h [32(decimal)] is space xor bh, bh ; set display page 0 mov bl, 1eh ; background of text is blue, foreground is yellow mov cx, 2000 ; 2000 x copy of space int 10h ; set cursor position mov ah, 02h mov dx, 0624h ; dh = 06h - dl = 24h (row - column) int 10h mov si, text_a call print_string ; set cursor position add dh, 02h ; rows = rows + 2 sub dl, 0fh ; column = column - 15 push dx ; column index saved mov ah, 02h int 10h mov si, text_b call print_string ; set cursor position pop dx ; load index of column add dh, 01h ; rows = rows + 1 mov ah, 02h int 10h push dx ; save cursor of column to next start writing text mov si, text_c call print_string ; set cursor position pop dx ; load index of column add dh, 02h ; rows = rows + 2 mov ah, 02h int 10h push dx ; save cursor of column to next start writing text mov si, text_d call print_string ; set cursor position pop dx ; load index of column add dh, 02h ; rows = rows + 2 add dl, 06h ; columns = columns + 6 mov ah, 02h int 10h mov si, text_e call print_string ;Save current Video mode (get Video mode and save it) mov ah, 0fh int 10h ; returns: current mode in al push ax ; save ; Read next character to select the choice mov ah, 01h int 21h cmp al, 31h ; 31h is 49 in decimal "1" jz short choice_1 cmp al, 32h ; 32h is 50 in decimal "2" jz short choice_2 ; other choice exit the program with next code ; wait for key press to exit program Exit: mov ah, 07h int 21h ret ; choices from the menu choice_1: ; horizontal color stripes xor ah, ah ; set graphic mode with resolution (640 x 480) mov al, 12h int 10h ;///////// xor bl, bl ; index pro proch?zen? barev mov si, barvy mov ah, 0ch ; Write pixel mov al, byte [si] xor cx, cx xor dx, dx ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; YBack: int 10h inc cx cmp cx, 640 jb short YBack xor cx, cx inc dx pusha ; ulo?en? registr? do z?sobn?ku mov ax, dx xor dx, dx mov bx, 120 div bx or dx, dx popa jnz short YBack inc bl cmp bl, 4 je text_continue inc si mov al, byte [si] jmp short YBack ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; choice_2: ; vertical color stripes xor ah, ah ; set graphic mode with resolution (640 x 480) mov al, 12h int 10h ;///////// xor bl, bl ; index pro procházení barev mov si, barvy mov ah, 0ch ; write pixel mov al, byte [si] xor cx, cx xor dx, dx ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; XBack: int 10h inc dx cmp dx, 480 jb short XBack xor dx, dx inc cx pusha ; uložení registrů do zásobníku mov ax, cx mov bx, 160 div bx or dx, dx popa jnz short XBack inc bl cmp bl, 4 je short text_continue_2 inc si mov al, byte [si] jmp short XBack ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; print_string_end2: mov ah, 02h ; Set cursor mov dh, 23 ; 23. ??dek mov dl, 35 ; 35. sloupec int 10h mov ah, 02h .print_char_eE: mov dl, [si] inc si or dl, dl jz short .DoneP int 21h jmp short .print_char_eE .DoneP: ret text_continue_2: ; vykreslení textu "Pres any key to continue" a překreslení pixelů mov si, text_f ;;;;;;;;;;;;;;; Write text call print_string_end2 call Graphic pop ax ; restore video mode int 10h jmp Exit ; nastavit skok do Main ;;;;;;;;;;;;;;; Graphic: mov cx, 280 ; počáteční sloupec (starting row) (left upper corner if string area) mov dx, 368 ; počáteční řádek (starting column)+ .ZBack: mov ah, 0dh ; BIOS funkce čtení pixelu int 10h cmp al, 00h jz short .writePixel .ContinueZBack: inc cx cmp cx, 488 jb short .ZBack mov cx, 280 inc dx cmp dx, 386 jb short .ZBack jmp short .DoneX .writePixel: mov di, barvy_kontrola mov ax, 0c02h ; pro pojištění kdyby nedopadla žádná podmínka (defaultní nastavení pixelu) cmp cx, 479 cmovg ax, [di] ;[barvy_kontrola] pusha mov si, text_b call print_string_end2 popa add di, 02h cmp cx, 319 cmovg ax, [di] add di, 02h cmp cx, 159 cmovg ax, [di] int 10h ; BIOS funkce pro zápis pixelu jmp short .ContinueZBack .DoneX: ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; text_continue: ; print text "Pres any key to continue" pop ax ; restore video mode int 10h mov si, text_f call print_string_end jmp Exit ; místo Exit nastavit do Main print_string: mov ah, 09h mov bl, 1eh ; background is blue, foreground is yellow mov cx, 01h .print_char: lodsb or al, al jz short .done int 10h push ax mov ah, 02h ; Bios function to set cursor position inc dl ; move cursor int 10h pop ax jmp short .print_char .done: ret print_string_end: mov ah, 02h ; Set cursor mov dh, 23 ; 23. ??dek mov dl, 35 ; 35. sloupec int 10h .print_string_e: mov ah, 02h .print_char_e: mov dl, [si] inc si or dl, dl jz short .Continue int 21h jmp short .print_char_e .Continue: mov si, barvy lea di, [barvy + 3] xor bl, bl ;Read pixel and write new pixel .ContinueColor: mov dx, 368 ; row mov cx, 280 mov ah, 0dh ; function of read graphic pixel .Gback: int 10h cmp al, [si] ; [si] <= mov si, barvy jnz short .GbackRow push ax mov ah, 0ch mov al, [di] ; [di] <= lea di, [barvy + 3] int 10h pop ax jmp short .GbackRow .GbackRow: inc cx cmp cx, 488 jb short .Gback mov cx, 280 ; start column inc dx cmp dx, 386 jb short .Gback lea si, [barvy + 4] mov di, barvy inc bl cmp bl, 02h jb short .ContinueColor ret ; Exit program Return: ret text_a: db "MENU", 00h text_b: db "1 - HORIZONTAL STRIPES", 00h text_c: db "2 - VERTICAL STRIPES", 00h text_d: db "Q - QUIT", 00h text_e: db "ENTER CHOICE:", 00h text_f: db "Press any key to continue", 00h barvy: db 00h, 05h, 0eh, 01h, 0fh ; color Black, Magenta, Yellow, Dark blue; White barvy_kontrola: db 0ch, 01h, 0ch, 0eh, 0ch, 05h
我想使用子例程

Graphic(代码下方)在图形模式 12h 下重绘文本区域的背景。文本区域为“1 - HORIZONTAL STRIPESnue”,以适合图形垂直条纹的图形像素。

我使用FASM汇编器。

assembly dos fasm operands conditional-move
1个回答
3
投票
第一次使用

cmovg指令时程序崩溃

首先确保您有权访问此特定说明。您可以通过检查

cpuid

 指令的结果来了解其可用性:

mov eax, 1 cpuid ; -> EAX EBX ECX EDX bt edx, 15 jnc NotSupported
如果在这里设置了进位标志,那么使用

cmovg

(和朋友)将会是安全的。

如果

cmovg

 确实有效,那么 
barvy_kontrola 数组中就会出现一个重要错误。

barvy_kontrola: db 0ch, 01h, 0ch, 0eh, 0ch, 05h

由于 x86 是小端架构,因此从该数组加载 AX 会将 BIOS 函数编号放入 AL 寄存器中,而不是放入其所属的 AH 寄存器中。不过颜色是 AL 的。

您可以写:

barvy_kontrola: dw 0C01h, 0C0Eh, 0C05h

barvy_kontrola: db 01h, 0Ch, 0Eh, 0Ch, 05h, 0Ch
    
© www.soinside.com 2019 - 2024. All rights reserved.