使用字符GUI TASM Assembly打印到屏幕数组中

时间:2017-11-22 23:12:37

标签: arrays string assembly tasm

下午好,我正试着在屏幕上用GUI Turbo Asembler TASM显示一串字符串,这个问题我不能只显示所有字符串。如果有人可以帮我正确显示屏幕上的字符串并浏览该数组,那就非常感激了 -

这是Borland C ++中的一个例子

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

1 个答案:

答案 0 :(得分:0)

嗯..我决定写一些高级版的显示板...我知道纯代码的答案并不好,但我在代码中添加了很多注释,使其更清晰,如何工作。

有关使用概念的一些提示:

我直接写入VGA text video memory,避免使用BIOS / DOS服务(在绘制游戏板等情况下使用它们很慢而且很麻烦)。

board数据不仅包含字母,还包含每个"字母"的最高位(80h值)。用作已使用/未使用的标记。绘图程序将根据该位的值更改字母的颜色。

即。董事会中的值41h将作为"未使用的A"和值41h + 80h = 0C1h将用作"使用A"。

未使用/使用过的字母具有light_magenta / white颜色,从使用的位计算并利用字母ASCII值的40h位。 (数字将具有bright_red / yellow颜色,如'0' = 30h,因此ASCII数字代码不包含40h位设置=不同的颜色计算结果。)

光标被"绘制" +"隐藏"通过在原始字母颜色上添加/减去颜色。

代码墙(使用TASM 4.1在dosbox下测试):

.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 ds=@DATA, 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 ds=@DATA, 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

使用Turbo调试器单步执行指令,并观察它们如何影响CPU状态以及它们如何修改内存(在选项屏幕中设置为"始终交换",以使直接视频RAM写入可见用户界面(Alt + F5))。尝试了解所有内容,以及旧代码,工作原理以及出现问题的地方。

相关问题