TASM 无限循环 [英] TASM infinite loop

查看:44
本文介绍了TASM 无限循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的程序中的问题是当我尝试从包含字符串的缓冲区中取出一个字符时,将一个字符分配给 AL 寄存器并调用一个过程,该过程将 AL 中的字符转换code>AL 到十六进制,我得到一个无限循环.这是我的代码:

The problem in my program is when I try to take a character from a buffer which contains a string of characters, assign one character to AL register and call a procedure, which converts the character in AL to HEX, I get an infinite loop. Here is my code:

.model small
.stack 100H

.data

about           db 'example.exe [/?] [sourceFile2]]',13,10,13,10,9,'/? - help',13,10,'$'
err_s           db 'Unable to open source file',13,10,'$'
str_term        db '$'
sourceF         db 12 dup (0)
sourceFHandle   dw ?
buffer          db 500 dup (?)

.code

START:
    mov ax, @data
    mov es, ax                  ; es so we can use stosb function: Store AL at address ES:(E)DI

    mov si, 81h

    call    skip_spaces

    mov al, byte ptr ds:[si]    ; read first symbol of program parameter
    cmp al, 13                  ; if there's no parameters
    jne _1
    jmp help                    ; then jump to help
_1:

    ;; do we need to print out help
    mov ax, word ptr ds:[si]
    cmp ax, 3F2Fh               ; if input is "/?" - 3F = '?'; 2F = '/'
    jne _2
    jmp help                    ; if "/?" is found, print out help

_2:

    ;; source file name
    lea di, sourceF
    call    read_filename       ; move from parameter to line

    push    ds
    push    si

    mov ax, @data
    mov ds, ax

    jmp startConverting

readSourceFile:
    pop si
    pop ds

    ;; source file name
    lea di, sourceF
    call    read_filename           ; move from parameter to line

    push    ds
    push    si

    mov ax, @data
    mov ds, ax

    cmp byte ptr ds:[sourceF], '$'  ; if there was nothing to read
    jne startConverting
    jmp closeF

startConverting:
    ;; open
    cmp byte ptr ds:[sourceF], '$'  ; if there was nothing to read
    jne source_from_file

    mov sourceFHandle, 0
    jmp read

source_from_file:
    mov dx, offset sourceF          ; file name
    mov ah, 3dh                     ; open file command
    mov al, 0                       ; 0 - reading, 1-writing
    int 21h                         ; INT 21h / AH= 3Dh - open existing file
    jc  err_source                  ; CF set on error AX = error code.
    mov sourceFHandle, ax           ; save filehandle

read:
    mov bx, sourceFHandle
    mov dx, offset buffer           ; address of buffer in dx
    mov cx, 500                     ; how many bytes to read
    mov ah, 3fh                     ; function 3Fh - read from file
    int 21h

    mov cx, ax                      ; bytes actually read
    cmp ax, 0                       ; if there was nothing to read
    jne _6                          ; not the end of file

    mov bx, sourceFHandle           ; end of the file being read
    mov ah, 3eh                     ; close the file
    int 21h
    jmp readSourceFile              ; open another file to read if it was specified in the parameters
_6:
    mov si, offset buffer           ; read from buffer

    cmp sourceFHandle, 0
    jne _7
    cmp byte ptr ds:[si], 13
    je  closeF
_7:
    push    cx                      ; save big loop CX

sort_out:
    lodsb                           ; Load byte at address DS:(E)SI into AL
    push    cx                      ; place cx
    mov ah, 40h                     ; INT 21h / AH= 40h - write to file
    int 21h
    pop cx
    loop    sort_out

    pop cx

    loop    read

help:
    mov ax, @data
    mov ds, ax

    mov dx, offset about         
    mov ah, 09h
    int 21h

    jmp _end

closeF:
    ;; close the destination file
    mov ah, 3eh                     ; close
    int 21h

result:
    MOV si, offset buffer           ; source index = buffer coordinates
    INC si                          ; add 1 to si
    MOV bh, [si]                    ; let bh know how many symbols in total
    INC si                          ; go to the symbol itself

    mov bl, 0                       ; initialize bl counter to 0

    jmp char

    ; print out the text in buffer
    mov dx, offset buffer
    mov ah, 09h
    int 21h

_end:
    ; add a string terminator to avoid static output
    db '$'
    mov ax, @data

    mov ax, 4c00h
    int 21h  

char:
    LODSB                               ; take a character from es:si and add it to al

    ; increment bl
    INC bl

    MOV dl, al                          ; add a symbol from al to dl
    mov ah,2
    int 21h

    ; try to convert the current symbol in al to HEX and print it out

    ; =======INFINITE LOOP PROBLEM HERE========
    call char_to_hex

    DEC bh                              ; subtract 1 from total amount of symbols
    JZ _end                             ; if bh = 0, end program
    JMP char                            ; if not, jump to other symbol

err_source:
    mov ax, @data
    mov ds, ax

    mov dx, offset err_s        
    mov ah, 09h
    int 21h

    mov dx, offset sourceF
    int 21h

    mov ax, 4c01h
    int 21h 

;; procedures

skip_spaces PROC near

skip_spaces_loop:
    cmp byte ptr ds:[si], ' '
    jne skip_spaces_end
    inc si
    jmp skip_spaces_loop
skip_spaces_end:
    ret

skip_spaces ENDP

read_filename PROC near

    push    ax
    call    skip_spaces
read_filename_start:
    cmp byte ptr ds:[si], 13        ; if there is no parameters
    je  read_filename_end           ; if yes, its the end of the filename
    cmp byte ptr ds:[si], ' '       ; if space
    jne read_filename_next          ; then skip it and jump to the next parameter
read_filename_end:
    mov al, '$'                     ; add '$' to the end
    stosb                           ; Store AL at address ES:(E)DI, di = di + 1
    pop ax
    ret

read_filename_next:
    lodsb                           ; loads other symbol
    stosb                           ; Store AL at address ES:(E)DI, di = di + 1
    jmp read_filename_start

read_filename ENDP

; Char to Hex converting
char_to_hex PROC                   ; Accept a character, print it's ascii value in hex.

        MOV DX, OFFSET AskChar      ; Display prompt
        MOV AH, 09H
        INT 21H

        MOV AH, 07H                 ; Get keyboard input w/ no echo (AL)
        INT 21H

        MOV CL, AL                  ; Copy user input (AL) to CL
        MOV AX, 0                   ; Clear AX (get rid of HO bits)
        MOV AL, CL                  ; Copy user input back into AL

        MOV BX, 16                  ; Set up the divisor (base 16)
        MOV CX, 0                   ; Initialize the counter
        MOV DX, 0                   ; Clear DX

        Div2:                         
                                    ; Dividend (what's being divided) in DX/AX pair, Quotient in AX, Remainder in DX.
            DIV BX                  ; Divide (will be word sized).
            PUSH DX                 ; Save DX (the remainder) to stack.

            ADD CX, 1               ; Add one to counter
            MOV DX, 0               ; Clear Remainder (DX)
            CMP AX, 0               ; Compare Quotient (AX) to zero
            JNE Div2              ; If AX not 0, go to "Div2:"

        getHex2:
            MOV DX, 0               ; Clear DX.
            POP DX                  ; Put top of stack into DX.
            ADD DL, 30h             ; Conv to character.

            CMP DL, 39h
            JG MoreHex2

        HexRet2:        

            MOV AH, 02h             ; 02h to display AH (DL)
            INT 21H                 ; Send to DOS

            LOOP getHex2            ; If more to do, getHex2 again
                                    ; LOOP subtracts 1 from CX. If non-zero, loop.
            JMP Skip2
        MoreHex2:
            ADD DL, 7h
            JMP HexRet2             ; Return to where it left off before adding 7h.
        Skip2:
            RET
    char_to_hex ENDP

end START

我的任务是得到这样的输出:

My assigment is to get an output like this:

00000000 4d 61 6e 6f 20 62 61 74 61 69 20 62 75 76 6f 20 ¦Mano batai buvo ¦
00000010 64 75 2c 0a 56 69 65 6e 61 73 20 64 69 6e 67 6f ¦du,.Vienas dingo ¦
00000020 20 2d 20 6e 65 72 61 6e 64 75 2e 0a 41 f0 20 73 ¦ - nerandu..Aš s ¦
00000030 75 20 76 69 65 6e 75 20 62 61 74 75 6b 75 0a 4e ¦u vienu batuku.N¦
00000040 69 65 6b 75 72 20 65 69 74 69 20 6e 65 67 61 6c ¦iekur eiti negal ¦
00000050 69 75 2e 0a ¦iu..¦
00000054

即使我的程序需要更多的工作才能得到这样的结果,但我至少希望正确地将字符转换为十六进制部分.

Even though my program needs more work to get such a result, I at least would like to get the converting chars to hex part right.

推荐答案

您是否从另一个练习中提取了 char_to_hex 并将其粘贴到此程序中?这将解释这部分:

Did you take char_to_hex from another exercise and paste it into this program? That would explain this part:

; Char to Hex converting
char_to_hex PROC                   ; Accept a character, print it's ascii value in hex.

    MOV DX, OFFSET AskChar      ; Display prompt
    MOV AH, 09H
    INT 21H

    MOV AH, 07H                 ; Get keyboard input w/ no echo (AL)
    INT 21H

我在任何地方都找不到 AskChar 符号,所以谁知道正在打印什么 - 但最后两行(耐心地)在键盘上等待给它一个字符.这可能是无限循环"吗?

I can't find the AskChar symbol anywhere, so who knows what is being printed - but the last two lines wait (patiently) on the keyboard to give it a character. Could that be the "infinite loop"?

这篇关于TASM 无限循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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