ASM x86零终结器

时间:2015-11-18 11:55:09

标签: assembly x86 tasm

打印存在一些问题。如果我使用美元终止字符串,它工作正常。但现在我想通过char打印char,直到找到零终结符。不幸的是,我得到了一个无限循环,它只是打印出第一个字符,而不是别的。

.model small
.stack 100h
.data
      input     db 40 dup (?) 
      filename  db 40 dup(?)    

.code   

main:                                                      
      mov ax,seg input
      mov ds,ax

      mov dx,offset input
      mov di, dx 

      mov bx, 82h
      mov cl,[es:80h]  

      mov al,[es:bx]
      cmp al, '-'       
      je increme                

worde:   
      mov al,[es:bx]

      mov [ds:di],al
      inc bx
      inc di

      cmp al,0Dh   ;enter?
      je endprogram

      cmp al, '-'
      jne worde ; if not equal, read next char

      dec di ;overwrite '-' 
    ;-----------------------------------------------------------------;
    ;------------------PRINT IT---------------------------------------;
    ;-----------------------------------------------------------------;
      mov al, 0  ;line terminate
      mov [ds:di], al

print:
      lea bx, input
      mov dl, [bx]

      cmp dl, 0
      je endproc

      mov ah, 02h
      int 21h 

      inc bx
      jmp print

endproc:    
      call new_line
next:
      mov dx,offset filename
      mov di, dx 

worde2:   
      mov al,[es:bx]

      cmp al, '-'       
      je increme         

      mov [ds:di],al
      inc bx
      inc di

      cmp al,0Dh   ;enter?
      je endprogram

      cmp al,20h   ;space? 
      jne worde2
    ;-----------------------------------------------------------------;
    ;------------------PRINT IT---------------------------------------;
    ;-----------------------------------------------------------------;
      mov al, 0  ;line terminate
      mov [ds:di], al
print2:
      lea bx, filename
      mov dl, [bx]

      cmp dl, 0
      je endproc2

      mov ah, 02h
      int 21h 

      inc bx
      jmp print2

endproc2:    
      call new_line
      jmp endprogram

increme:
      inc bx
      jmp worde
increme_next:
      inc bx
      jmp next

endprogram:
      mov ah,4ch   ;end program
      int 21h

new_line:
   push ax
   push bp
   mov ax,0e0ah 
   int 10h
   mov al,13     ;carriage return
   int 10h 
   pop bp
   pop ax
ret

end main

修改:经过少量修改后,仍会收到一些奇怪的字符: weird chars

修正: 只需保存bx注册表,以便日后使用pushpop指令。就是这样

1 个答案:

答案 0 :(得分:2)

我经常使用此函数来打印字符串。我更喜欢使用int 10h,因为它可以在POST后立即使用,并且可以在实模式环境中使用,无论是否加载DOS。 (即引导加载程序)

;-----------------------------------------------------------------------------------
;void PrintString(char *str)
; assumes that DS already holds the seg that contains the string - we're only passing a near pointer
PrintString:
    push    bp
    mov     bp, sp

    push    ax
    push    si

    mov     si, [bp+4]      ; si = str
.getChar:
    lodsb                   ; load a char
    test    al, al          ; is it zero
    jz      .done           ; if so, we're done.
    mov     ah, 0x0e
    int     0x10            ; print the char
    jmp     .getChar        ; and go back for the next one
.done:

    pop     si
    pop     ax

    pop     bp
    ret     2               ; return and remove the argument (*str) from stack.

使用它就像:

[section .text]
...
push  word .someString
call  PrintString
...
[section .data]
.someString  db 'Hello World!', 10, 13, 0

我使用过NASM语法 - 您需要在适当的位置添加所需的关键字,例如ADDR