Turbo汇编语言光标位置,偏移量 [英] Turbo assembler language cursor position, offset
问题描述
我们已发出指令,使文本CSC 112.1居中.我使用了DB指令和偏移量. 这是我的代码
We have given an instruction to make the the text CSC 112.1 to be centered. I used DB instruction and offset. This is my code
.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
输出是这个并且仅在左侧.
The output is this and only at the left side.
为什么它不在我的光标位置显示?而且我的DB指令仅是一个示例,即c.
What's the reason why it doesn't show in my cursor position? And also my DB instruction is only one as an example, which is c.
有什么建议吗?需要帮助!
Any suggestion? Need help!
推荐答案
如果所有字符都以与C相同的方式定义,则光标设置只是设置正确的起始行,但是任何13,10新行都会重置光标开始下一行.
If all the characters are defined same way as that C, then the cursor set is just setting correct starting line, but any 13,10 new line will reset cursor to start of next line.
此外,DOS结束行是13,10,而不是10,13.
Also the DOS end line is 13,10, not 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值).
About this, the cursor position should be in DH
= row, DL
= column. But 43h isn't column=3, row=4. It's column 67, row=0. To load DH=4, DL=3
you would have to do mov dx,403h
or to have it more nicely byte vs byte mov dx,0403h
In hexadecimal formatting single digit = 4 bits, so two digits = 8 bits (one small register). "43h" covers just single register (DL
), DH
is then 00h
. Or if you don't get the idea of hexadecimal 1 digit = 4 bits, then you can use mov dx,3 + 4*256
(the higher byte is *256 value).
如果要在特定位置输出这样的字母,则必须更改定义,以不包括换行符.即:
If you want to output such letter on certain position, you will have to change the definition, to NOT include newline characters. I.e.:
c label byte
db " лллл "
db " лллллл "
db "лл лл"
db "лл "
db "лл "
db "лл "
db "лл "
db "лл "
db "лл "
db "лл лл"
db " лллллл "
db " лллл "
每个字符将其输出8x12次,而不是将ah = 9作为单个字符串输出.
And output it per char, 8x12 times, not with ah=9 as single string.
由于您的字母是8个字符宽,并且具有单个可打印字符,因此您实际上可以将这些数据存储为位,即
And as your letter is 8 chars wide, and with single printable character, you can actually store those data as bits, i.e.
; C letter, 8x12 bitmask
c db 03Ch, 07Eh, 0C3h, 0C0h, 0C0h, 0C0h
db 0C0h, 0C0h, 0C0h, 0C3h, 07Eh, 03Ch
如果您希望每行超过8个字符(点"),这会中断,就像我怕您的数字"定义确实会使用,但是您可以使用单独的数字来构建它,但是随后您需要比例字体,即在位掩码之前再添加一个值,定义字形的宽度" ...让我们将其增加到16位值,再加上比例/大小信息:
This will break if you want more than 8 characters ("dots") per line, like I'm afraid your "number" definition does use, but you can build it from separate digits, but then you would need proportional font, i.e. to add one more value ahead of bitmask, defining "width" of glyph... let's do that, bump it to 16 bit values plus proportional/size info:
; 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",例如"Ɔ".并且我添加了一些实心的正方形和空格以验证打印例程:
And I finally "mirrored" the bit data, so the left-most dot on screen is in lowest bit (which is "right-most" in binary/hexadecimal), so letter "C" is defined in bitmask like "Ɔ". And I added some filled squares and spaces to verify the print routine:
; 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
我对源代码进行了广泛评论,因此希望可以理解如何打印位掩码数据的机制.如果没有,请首先尝试调试器(以观察值在打印循环内的寄存器中如何演化),如果仍然令人困惑,请不要尝试随时在这里问.
I commented source extensively, so hopefully the mechanics of how the bitmask data are printed is understandable.. if not, try debugger first (to watch how values evolve in the registers inside the print loop), if it still confusing, don't hesitate to ask here.
这篇关于Turbo汇编语言光标位置,偏移量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!