我们已经给出了使文本CSC 112.1居中的指令。我使用DB指令和偏移量。 这是我的代码
.model small
.stack
.data
c db 10,13,10,13," лллл ",10,13
db " лллллл ",10,13
db "лл лл",10,13
db "лл ",10,13
db "лл ",10,13
db "лл ",10,13
db "лл ",10,13
db "лл ",10,13
db "лл ",10,13
db "лл лл",10,13
db " лллллл ",10,13
db " лллл ",10,13,"$"
.code
mov ax,@data
mov ds,ax
call ccall ;call the procedure ccall which outputs C
call scall ;call the procedure scall which outputs S
call numcall ;call the procedure numcall which outputs 112.1
call exit ;call the procedure exit and end terminate the program
ccall proc ;procedures
mov ah,02h
mov bh,00
mov dx,043h ;set the cursor position where "04 is y coordinate" and "3 is x coordinate"
int 10h
mov ah,09h ;ouputs a string
mov dx,offset c
int 21h
call delay
ccall endp ;end of the procedure ccall
scall proc
mov ah,02h
mov bh,00
mov dx,04ah ;set the cursor position where "04 is y coordinate" and "A is x coordinate"
int 10h
mov ah,09h ;ouputs a string
mov dx,offset s
int 21h
call delay
scall endp ;end of the procedure
numcall proc ;procedure
mov ah,02h
mov bh,00
mov dx,041dh ;set the cursor position where "04 is y coordinate" and "1D is x coordinate"
int 10h
mov ah,09h ;ouputs a string
mov dx,offset num
int 21h
call delay
numcall endp
exit proc
mov ah,4ch ;terminate process
int 21h
exit endp
delay proc
mov cx,300h
D: push cx
mov cx,0ffffh
E: loop E
pop cx
loop D
ret
delay endp
end
输出是这个,只在左侧。
它之所以没有显示在光标位置的原因是什么?而且我的DB指令只有一个例子,即c。
有什么建议吗?需要帮助!
答案 0 :(得分:1)
如果所有字符的定义方式与C相同,则光标设置只是设置正确的起始行,但任何13,10新行都会将光标重置为下一行的开头。
DOS端线也是13,10,而不是10,13。
mov ah,02h
mov bh,00
mov dx,043h
; set the cursor position where "04 is y coordinate"
; and "3 is x coordinate"
int 10h
关于此,光标位置应在DH
=行,DL
=列中。但是43h不是column = 3,row = 4。它是第67列,行= 0。要加载DH=4, DL=3
,您必须执行mov dx,403h
或更好地使字节与字节mov dx,0403h
在十六进制格式化单个数字= 4位,因此两位数= 8位(一个小寄存器) )。 “43h”仅涵盖单个寄存器(DL
),DH
则为00h
。或者如果你不知道十六进制1位= 4位,那么你可以使用mov dx,3 + 4*256
(高位字节是* 256值)。
如果要在特定位置输出此类字母,则必须更改定义,不包括换行符。即:
c label byte
db " лллл "
db " лллллл "
db "лл лл"
db "лл "
db "лл "
db "лл "
db "лл "
db "лл "
db "лл "
db "лл лл"
db " лллллл "
db " лллл "
按字符输出,8x12次,而不是ah = 9作为单个字符串。
由于你的信件是8个字符宽,并且具有单个可打印字符,你实际上可以将这些数据存储为位,即
; C letter, 8x12 bitmask
c db 03Ch, 07Eh, 0C3h, 0C0h, 0C0h, 0C0h
db 0C0h, 0C0h, 0C0h, 0C3h, 07Eh, 03Ch
如果你想要每行超过8个字符(“点”),这会破坏,比如我害怕你的“数字”定义确实使用,但你可以用不同的数字构建它,但是你需要比例字体,即在位掩码之前再添加一个值,定义字形的“宽度”......让我们这样做,将其加到16位值加上比例/大小信息:
; C letter, proportional width + 16x12 bitmask
c dw 0C09h ; width is 9 dots, height is 12 lines
dw 03Ch, 07Eh, 0C3h, 0C0h, 0C0h, 0C0h ; 16x12 bitmask
dw 0C0h, 0C0h, 0C0h, 0C3h, 07Eh, 03Ch
我最后“镜像”了位数据,因此屏幕上最左边的点位于最低位(二进制/十六进制中“最右边”),因此字母“C”在位掩码中定义为“ Ɔ”。我添加了一些填充的正方形和空格来验证打印例程:
; file: BIGLETER.ASM
; author: Peter Ped7g Helcmanovsky, (C) 2017
; license: CC0 (public domain)
; builded with TASM v4.1, TLINK v5.0 under dosbox v0.74 by commands:
; tasm /m5 /w2 /t /l bigleter
; tlink bigleter.obj
.model small
.stack
.data
; C letter, proportional width + 16x12 bitmask
; bitmask is "mirrored", the bottom (right) bit goes out first
; (left side of letter)
c dw 0C0Ah ; width is 10 dots (8 dots have pixels), height is 12 lines
dw 03Ch, 07Eh, 0C3h, 003h, 003h, 003h ; 16x12 bitmask
dw 003h, 003h, 003h, 0C3h, 07Eh, 03Ch
square12x12 LABEL WORD
dw 0C0Ch ; width is 12 dots, height is 12 lines
dw 0FFFh, 0FFFh, 0FFFh, 0FFFh, 0FFFh, 0FFFh ; 16x12 bitmask
dw 0FFFh, 0FFFh, 0FFFh, 0FFFh, 0FFFh, 0FFFh
space2d LABEL WORD
dw 0C02h ; width is 2 dots, height is 12 lines
dw 12 DUP (0) ; 16x12 bitmask
; (12 lines to clear screen over full common letter height)
space1d LABEL WORD
dw 0C01h ; width is 1 dot, height is 12 lines
dw 12 DUP (0) ; 16x12 bitmask
; (12 lines to clear screen over full common letter height)
.286
.code
start:
mov ax,@data
mov ds,ax
mov ax,3 ; ah=0, al=3 => VGA text mode 80x25
int 10h ; (expensive "clear screen")
; print 2x big C at specific position
mov dx,0604h ; row=6, column=4 starting position
mov si,OFFSET c ; data of "C" letter
call PrintBigLetter
mov si,OFFSET c ; data of "C" letter
call PrintBigLetter
; print white squares and different type of spaces
; (to test print routine well, including proportional feature)
mov si,OFFSET square12x12 ; data of filled square 12x12
call PrintBigLetter
mov si,OFFSET space2d ; data of 2 dots "space"
call PrintBigLetter
mov si,OFFSET square12x12 ; data of filled square 12x12
call PrintBigLetter
mov si,OFFSET square12x12 ; data of filled square 12x12
call PrintBigLetter
mov si,OFFSET space1d ; data of 1 dot "space"
call PrintBigLetter
mov si,OFFSET square12x12 ; data of filled square 12x12
call PrintBigLetter
; return to DOS with exit code 0
mov ax,4c00h
int 21h
; in: dh:dl = row:column, ds:si = letter definition
; out: dh:dl = row:column adjusted for next letter
; modifies: ax, bx, cx, si, di (basically ALL except dx and bp)
PrintBigLetter PROC
mov cx,[si] ; ch = line count, cl = column size
add si,2
; store next letter position on stack
add dl,cl
push dx
sub dl,cl ; restore position back for this letter
PBL_row_loop:
; set cursor to start of next line
mov ah,2
xor bh,bh
int 10h ; dh:dl = row:column to set (left dot on line)
; load "mirrored" bitmask and prepare for printing line
mov di,[si] ; di = bitmask of line
add si,2
mov ah,0Eh ; int 10h 0E service
; print CL-many dots on screen
push cx
PBL_dot_loop:
mov al,' ' ; space
shr di,1 ; bottom bit into CF
jnc PBL_dot_empty
mov al,0DBh ; 0xDB = '█' filled rectangle character
PBL_dot_empty:
; ah=0E, al=dot_char, bh=0, bl=? => ready to call int 10h
int 10h ; print single "dot" of char
dec cl ; print column-size many dots
jnz PBL_dot_loop
pop cx
; move to next line
inc dh ; next row
dec ch
jnz PBL_row_loop; CH-many rows
pop dx ; set dx to position of next letter
ret
ENDP
END start
我广泛评论了源码,所以希望如何打印位掩码数据的机制是可以理解的......如果没有,首先尝试调试器(观察值如何在打印循环内的寄存器中演变),如果它仍然令人困惑,请不要我在这里犹豫不决。