Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
215 views
in Technique[技术] by (71.8m points)

file - TASM infinite loop

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...