2017-11-22 14 views
-1

午後、GUI Turbo Asembler TASMで文字列の配列を表示しようとしています。すべての文字列を最初に表示することはできません。文字GUIで画面配列に印刷するTASMアセンブリ

Program in tasm:誰かは、Borland C++

Example

例実際にこのTASM中を私は正しく画面上に文字列を表示し、その配列を通って移動し、非常にgrateful-

これを助けることができる場合

コードは次のとおりです。

.MODEL small 

.STACK 100h ; reserves 256 bytes of uninitialized storage 

.DATA 
startX equ 35 
startY equ 8 
y db ? 
x db ? 
t1 db ? 
t2 db ? 
t3 db ? 

zSprite db'M','M','L','E','E','N','A','E','V','E', 
    db'E','R','H','O','N','G','O','S','T','R', 
    db'X','X','O','T','I','R','R','A','C','A', 
    db'I','S','A','P','P','O','T','A','P','S', 
    db'C','C','M','L','A','A','I','Z','O','T', 
    db'O','A','A','U','A','N','U','L','P','U', 
    db'S','O','M','B','R','E','R','O','M','P', 
    db'C','N','E','A','R','R','I','I','O','O', 
    db'W','O','J','E','N','O','C','P','Z','E', 
    db'A','A','Z','A','A','L','N','Y','T','D' 


.386 ;enabled assembly of non privileged 80386 instructions 
.CODE 
start: 
;set DS to point to the data segment 
mov ax,@data 
mov ds,ax 

mov di,offset zSprite 

mov y,0 

l5: 
cmp y,10 
jl l0 
jmp l1 

l0: 
mov x,0 

l4: 
cmp x,10 
jl l2 
jmp l3 

l2: 
mov al,startX 
add al,x 
mov t1,al 

mov al,startY 
add al,y 
mov t2,al 

; set cursor position at (x,y) 
mov ah,02h ;set cursor position service 
mov bh,00h ;page number 
mov dh,t2 ;row 
mov dl,t1 ;column 
int 10h ;bios interrupt 

mov ax,0 ;reset ax 
mov al,y ;ax = y 
mov bx,10 
mul bx ;ax = ax * 10 
mov bx,0 ;reset bx 
mov bl,x ;bx = x 
add ax,bx ;ax = ax + x 
mov bx,ax 

; set color 
mov ah,09h ;service 
mov al, zSprite;character 
mov bh,00h ;page number 
mov bl,[bx+di] ;color 
mov cx,01h ;number of times to print character 
int 10h 

;print symbol 
mov ah, 02h 
mov dl, zSprite 
int 21h 

inc x 
jmp l4 

l3: 
inc y 
jmp l5 

l1: 
nop 

exit: 
;DOS: terminate the program 
mov ah,4ch ; mov ax, 4c00h 
mov al,0h 
int 21h 

delay PROC 
pop bx 

mov ax,1000d 
mov dx,ax 

delay1: 
mov cx,ax 

delay2: 
dec cx 
jnz delay2 
dec dx 
jnz delay1 

push bx 

ret 
delay ENDP 

END start 
+0

Erm、あなた自身のコメント**は "mov al、0feh; character" _ ... that **はあなたの "写真"です。 – Jester

+0

私は悪い英語のために申し訳ありません。 誤った文字の代わりに文字を表示する方法がわかりません。ご協力いただきありがとうございます。 – raintrooper

+0

「間違っている」というわけではありません。 – Jester

答えて

0

うーん..私はディスプレイボードのやや高度なバージョンを書くことにした...、私は純粋なコードの答えは良いものではありません知っているが、私はそれがより明確にするために、コードの中に多くのコメントを追加しました使い方。

使用される概念についていくつかのヒント:

私はBIOS/DOSサービスを(彼らはゲームボードを描画するような場合に使用するのが遅く、面倒です)回避、VGA text video memoryに直接書いています。

データには文字だけでなく、各 "文字"の最上位ビット(80h)が使用/未使用マーカーとして使用されます。描画ルーチンは、このビットの値に基づいて文字の色を変更します。

I.e.ボード内の値41hは "未使用A"として機能し、値41h + 80h = 0C1hは "使用済みA"として機能します。

使用されていない/使用されていない文字はlight_magenta/white色を持ち、使用されたビットから計算され、文字ASCII値の40hビットも利用します。 (数字にはbright_red/yellowの色があり、'0' = 30hのように、ASCIIコードには40hビットセット=異なる色の計算結果が含まれていません)。

カーソルは、元の文字色に色を追加/減算することによって、「描かれた」+「隠されている」。


とコードの壁(dosbox下TASM 4.1でテスト):

.MODEL small 

.STACK 100h ; reserves 256 bytes of uninitialized storage 

.DATA 

BOARD_SIZE_X EQU  10 
BOARD_SIZE_Y EQU  10 
START_X   EQU  35 
START_Y   EQU  8 
CURSOR_COLOR EQU  0B0h  ; add "blink" + cyan background 

board LABEL BYTE 
    DB "MMLEENAEVE" 
    DB "ERHONGOSTR" 
    DB "XXOTIRRACA" 
    DB "ISAPPOTAPS" 
    DB "CCMLAAIZOT" 
    DB "OAAUANULPU" 
    DB "SOMBREROMP" 
    DB "CNEARRIIOO" 
    DB "WOJENOCPZE" 
    DB "AAZAALNYTD" 

cursor_x  db 5 
cursor_y  db 7 

.386 
.CODE 
start: 
    ;set DS to point to the data segment 
    mov  ax,@data 
    mov  ds,ax ; ds = data segment 
    mov  ax,0B800h 
    mov  es,ax ; es = text VRAM segment for direct VRAM writes 

    ; fake some characters being "used" to test drawing code 
    or  BYTE PTR [board+34],80h  ; mark the "POT" word 
    or  BYTE PTR [board+35],80h  ; on fourth line in middle 
    or  BYTE PTR [board+36],80h 

    call clear_screen 
    call draw_board 
    mov  dl,CURSOR_COLOR 
    call draw_cursor 

    ; wait for keystroke 
    xor  ah,ah 
    int  16h 

    ; fake "move cursor" 
    mov  dl,-CURSOR_COLOR  ; hide cursor on old position 
    call draw_cursor 
    inc  BYTE PTR [cursor_x]  ; move it up+right 
    dec  BYTE PTR [cursor_y] 
    mov  dl,CURSOR_COLOR   ; show cursor on new position 
    call draw_cursor 
    ; (other option would be to redraw whole board) 

    ; wait for keystroke before exit 
    xor  ah,ah 
    int  16h 
    ; exit to DOS 
    mov  ax,4C00h 
    int  21h 

; sets whole text video RAM to white "space" with red background 
; modifies ax, cx, di, assumes es=B800 
clear_screen PROC 
    xor  di,di ; B800:0000 target address 
    mov  ax,' ' + 4Fh*256 ; white space on red background 
    mov  cx,80*25 
    rep stosw  ; fill up video RAM with that 
    ret 
ENDP 

; redraws whole board to the video RAM, marks "used" characters too 
; modifies ax, cx, dx, si, di, assumes [email protected], es=B800 
draw_board PROC 
    mov  si,OFFSET board ; si = address of first letter of board 
    ; di = offset of starting position in video RAM 
    ; 2 bytes per char (char+color), 80 chars (160B) per line 
    mov  di,(START_Y*80 + START_X)*2 
    ; output BOARD_SIZE_Y lines 
    mov  dx,BOARD_SIZE_Y 
board_line_loop: 
    ; output BOARD_SIZE_X coloured characters 
    mov  cx,BOARD_SIZE_X 
board_char_loop: 
    lodsb   ; al = next character + used bit, advance si +1 
    mov  ah,al ; color of unused/used will be: 12 + 1 || 3 = 13 || 15 
    and  al,7Fh ; clear the top bit (used/unused): al = ASCII letter 
    shr  ah,6 ; ah = 1 || 3 (80h "used" bit + 40h bit from letter code) 
    add  ah,12 ; ah = 13 || 15 by "used" bit (magenda/white on black) 
    stosw   ; write letter+color to VRAM es:di, advance di +2 
    dec  cx 
    jnz  board_char_loop ; loop till whole line is displayed 
    ; move video ram pointer to start of next line 
    add  di,(80-BOARD_SIZE_X)*2 ; advance to start of next line 
    dec  dx 
    jnz  board_line_loop ; loop till every line is displayed 
    ret 
ENDP 

; Modifies letter color at current cursor position by adding DL 
; modifies ax, di, assumes [email protected], es=B800 
draw_cursor PROC 
    mov  al,[cursor_y] 
    mov  ah,160 
    mul  ah  ; ax = cursor_y * 160 
    movzx di,BYTE PTR [cursor_x] ; di = zero-extended cursor_x 
    add  di,di ; di *= 2 (cursor_x*2) 
    add  di,ax ; di += cursor_y * 160 
    ; add initial board offset and +1 to address attribute only 
    add  di,(START_Y*80 + START_X)*2 + 1 
    add  es:[di],dl ; modify letter color by adding DL 
    ret 
ENDP 

END start 

コマンドは、exeファイルを構築するために使用:

REM source file has name: wordgame.asm 
tasm /m5 /w2 /t /l wordgame 
tlink wordgame.obj 

使用ターボデバッガシングルステップへそれらがCPUの状態にどのように影響し、どのようにメモリを変更するかを見る(オプションの画面では " (Alt + F5))を表示するために、「常にスワップ(swap always)」を選択します。すべてのこと、古いコード、それがどのように働いているのか、どこに問題があるのか​​を理解しよう。

+0

ありがとうございました。私はそれを分析し、より多くを学ぶために私の間違いを見直します。 – raintrooper

+1

@ restrictrooper残念ながら、これはあなたのコードの問題を説明していませんが、それはもっとチャットするだろうし、あなたはすぐに自分のものをいくつか特定することができます。いくつかのデバッガ(TASMインストールの一部として使用されていたターボデバッガ)を入手し、それを使って単一の命令をチェックする方法を学び、CPUが実際に行っていることに対する期待を常に検証しようとします(また、 http://x86.renejeschke.de/や公式インテルのドキュメントなど)。また、私のコードで特定のことを理解していない場合は、尋ねてください。 – Ped7g

関連する問題