Assembly 以下代码应在视频模式下打印jan字符串,但它会打印一些符号。我应该如何打印一月?

Assembly 以下代码应在视频模式下打印jan字符串,但它会打印一些符号。我应该如何打印一月?,assembly,x86,Assembly,X86,将字符串直接显示到0B800h中的过程: .model small .data Jan db " January " .code .386 mov ax, 0B800h ; (assign first address of video memory to AX) mov es, ax sub di,di mov cx, 25*80 mov ax, 00h ; (17h is blue backg

将字符串直接显示到0B800h中的过程:

.model small
.data

Jan   db  "         January           "

.code
.386            

mov ax, 0B800h      ; (assign first address of video memory to AX)
mov es, ax
sub di,di
mov cx, 25*80


mov ax, 00h         ; (17h is blue background, white foreground. 20h is blank space in ASCII)

L:     mov es:[di], ax   ;  (20h gets stored in the even addresses, 17h gets stored in odd)
       add di, 2
       loop L

MOV di, 560         ;(? = position you want to write to (160*y + 2*x))
MOV ah, 17h         ;(? = attribute like 17h)
MOV cx, 27      ;(? = length of string. Here "hello world" is 11 characters long)
MOV si, offset Jan  ;(si has the address of the first character of myMessage)
L1:     mov al, [si]
        mov es:[di], ax
        add di, 2
        inc si
        loop L1

您可能忘记初始化
ds
。此外,您的第一个循环设置错误:
mov ax,00h
根据注释,当然应该是
mov ax,1720h
。好的,H.N.,在我编辑的答案中有您的程序。如果您想显示任意多的字符串,请多次调用它。谢谢,这是可行的,但另一件事是,如果我必须立即正确打印整个月,我可以在这里做什么?在过程中转换代码,此过程将变量的偏移量作为参数(以及X、Y和颜色)。所以,每次需要打印字符串时。只需给程序打电话。
.model small
.stack 100h
.data

Jan   db  "         January           "
Me    db  "  By josmanaba@yahoo.com   "
x     dw ?
y     dw ?
color db ?

.code

;INITIALIZE DATA SEGMENT.
mov ax, @data
mov ds, ax

mov ax, 0B800h      ; (assign first address of video memory to AX)
mov es, ax      

;DISPLAY JAN.                
mov  x, 40
mov  y, 12
mov  color, 17h
mov  di, offset jan
mov  cx, 27  ;STRING LENGTH.                 
call displayB800

;DISPLAY ME.
mov  x, 50
mov  y, 22
mov  color, 37h
mov  di, offset Me
mov  cx, 27  ;STRING LENGTH.                 
call displayB800

;FINISH PROGRAM.    
mov ax, 4c00h
int 21h

;----------------------------------------------
;PARAMETERS : VARIABLES X,Y,COLOR.
;             STRING OFFSET IN DI.
;             STRING LENGTH IN CX.
;ASSUME ES = 0B800H.

proc displayB800
displaying:
;GET Y (Y*160).
  mov  ax, y    
  mov  bl, 160 ;ONE TEXT LINE = 80*2 BYTES.
  mul  bl  ;Y*160.  
;GET X (X*2).
  mov  bx, x
  shl  bx, 1  ;X*2 BECAUSE IT'S CHAR/ATTR. SHL=PUSH ONE BIT LEFT (FAST MULTIPLY BY 2).
;X,Y TOGETHER (Y*160 + X*2). THIS IS THE OFFSET INSIDE B800.  
  add  bx, ax   
;PUT CHAR IN POSITION X,Y.  
  mov  ah, color
  mov  al, [ di ]  ;CURRENT STRING CHAR.
  mov  es:[ bx ], ax  ;NOTICE BX IS OFFSET INSIDE 0B800H.
;NEXT CHAR.  
  inc  di  
  inc  x
  loop displaying

  ret
endp