2017-11-22 22 views
-1

안녕하세요, 오후에 GUI Turbo Asembler TASM으로 문자열 배열을 표시하려고합니다. 모든 문자열을 첫 번째로만 표시 할 수는 없습니다. 누군가가 나 제대로 화면에 문자열을 표시하고 ++ 볼랜드 C에서문자 GUI로 화면 배열로 인쇄 TASM 어셈블리

이 예를 들어, 매우 grateful- 그 배열을 통해 이동 도움이 될 수있는 경우

Example

TASM에서이 실제로

:

Program in tasm

코드는 다음과 같습니다. ,

.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"_ ... ** ** 당신의 "picture"입니다. – Jester

+0

나쁜 영어로 유감입니다. 잘못된 문자 대신 문자를 표시하는 방법을 모르겠습니다. 당신의 도움을 주셔서 감사합니다. – raintrooper

+0

"잘못된"것이 아니라 프로그램이 말한 것입니다. – Jester

답변

0

은 흠 .. 나는 순수 코드의 대답은 좋은 사람하지 알고 ... 디스플레이 보드의 다소 진보 된 버전을 쓰기로했다,하지만 난 그게 더 명확하게 할 수있는 코드로 많은 코멘트를 추가 어떻게 작동하는지. 사용 개념에 대한

몇 가지 힌트 : 나는 (그들이 게임 드로잉 보드 같은 경우에 사용하는 것이 느리고 성가시다) BIOS/DOS 서비스를 피하고, VGA text video memory에 직접 쓰고 있어요

.

데이터는 문자뿐만 아니라 각 "문자"의 최상위 비트 (80h 값)가 사용/사용되지 않은 마커로 사용됩니다. 드로잉 루틴은이 비트의 값에 따라 글자 색을 변경합니다.

e.e. 값 41h은 "unused A"로 작동하고 값 41h + 80h = 0C1h은 "used A"로 작동합니다.

사용되지 않은/사용되지 않은 문자는 light_magenta/white 색을 사용합니다. 사용 된 비트에서 계산되어 문자 ASCII 값의 40h 비트를 사용합니다. (숫자는 bright_red/yellow 색상을 가지므로 '0' = 30h이므로 ASCII 숫자 코드에는 40h 비트 세트 = 다른 색상 계산 결과가 포함되지 않음).

원래의 문자 색상에 색상을 더하고/빼서 커서를 "그린"+ "숨김"합니다.


그리고 코드의 벽

은 ( dosbox에서 TASM 4.1 테스트) :

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

사용 터보 디버거 하나의 단계 :

.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를 구축하는 데 사용 지침을 검토하고 CPU 상태 및 메모리 수정 방법에 영향을주는 지 확인하십시오 (옵션의 화면에서 " 항상 스왑 "하여 사용자 비디오 화면에 직접 비디오 RAM 쓰기를 표시합니다 (Alt + F5). 모든 것을 이해하고 오래된 코드와 작동 방식, 문제가있는 곳을 이해하십시오.

+0

정말 고마워요. 나는 그것을 분석하고 더 많은 것을 배우기 위해 나의 실수를 검토 할 것이다. – raintrooper

+1

@ limitingrooper 불행히도 이것은 코드의 문제를 설명하지는 않지만 더 많은 채팅이 될 것이며 더 많은 경험을 얻을 수있을 것입니다. 그냥 몇 가지 디버거 (TASM 설치의 일부로 사용되는 터보 디버거)를 사용하고 단일 명령어를 검사하는 방법을 배우고 CPU가 실제로하는 것에 대한 기대를 확인하려고 시도하십시오 (지침에도 참조 가이드를 사용하십시오. http://x86.renejeschke.de/ 또는 공식 Intel 문서). 또한 당신이 내 코드에서 특정 것을 이해하지 못한다면, 그냥 물어보십시오. – Ped7g