Turbo汇编语言光标位置,偏移量 [英] Turbo assembler language cursor position, offset

查看:107
本文介绍了Turbo汇编语言光标位置,偏移量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们已发出指令,使文本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),然后DH00h.或者,如果您不知道十六进制的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆