Home > Back-end >  How to check if there is newLine YASM 8086
How to check if there is newLine YASM 8086

Time:12-08

I've been working on the project. The main goal is to calculate how many words do not contain letters from 'a' to 'k'. Given file has [0;1000] lines. Every line contains 6 columns.

The first two columns contain string with [1; 20] characters. Characters could be letters, numbers, and whitespaces.

3-5 columns contain integers in the range [-100; 100]. 6th column contains real numbers in the range [-9.99; 9.99] with only two digits after the decimal point.

Each section I separated by a semicolon ';'.

helloA;lB;lC;lD;lE;lF
A11;bas morning;0;0;5;1.15

My problem is, that if there is a newLine at the end of the file, skip them, and sum up them in the final count.

TASK: calculate how many words (the word is one or more symbols without ' '(space)) in the first two columns do not contain letters 'B' or 'C'. And print that integer number.

I have tried to compare al with 0x20 and jump to the next section if it is smaller, but that didn't help me.

What I have done so far

        ; Main 
        .whileNotTheEndOfFile:
            mov si, 2
            call procSkaitytiEilute
            
            ; Check the first two columns
            ;mov al, ';'

        mov di, line
        .skipSpaces:
            mov al, [di]
            inc di
            cmp  al, ' '
            je .skipSpaces
            cmp  al, ';'
            je .q3
            dec di

        .checkWord:
            mov bx, 1

        .q1:
            mov  al, [di]
            inc  di
            cmp  al, ' '
            je   .q2
            cmp  al, ';'
            je   .q2
            jmp .q8

        .q8:
            cmp al, 20h
            jl .skipLine
            jmp .q7

        .q7:
            cmp al, 'A'
            jl .q5
            jmp .q4

        .q4:
            cmp  al, 'K'
            jae .q5
            mov  bx, 0       ; One or more invalid chars in current word
            jmp  .q1
        
        .q5:
            cmp al, 'a'
            jae .q6
            jmp .q1       

        .q6:
            cmp al, 'k'
            jae .q1      
            mov bx, 0
            jmp .q1


        .q2:
            add  [lineCount], bx  ; BX=[0,1] Counting the 'good' words
            cmp  al, ';'
            jne  .skipSpaces
        .q3:
            dec  si          ; Next column?
            jnz  .skipSpaces
            .skipLine:
            cmp  [readLastLine], byte 0
            je   .whileNotTheEndOfFile
            
            ; Jeigu ne failo pabaiga, kartojame cikla
            .skipLine:
            sub [lineCount], 2
            cmp [readLastLine], byte 0
            je .whileNotTheEndOfFile
            
            ; Hexadecimal convertion to decimal
           mov dx, lineCount
           mov ax, [lineCount]
           call procUInt16ToStr
           call procPutStr
           macNewLine
           mov si, dx


           .writeToFile:
           lodsb
           cmp al, 0
           jne .writeToFile
           sub si, dx
           lea cx, [si-1]
           mov bx, [writingDescriptor]
           mov ah, 40h
           int 21h

        ; Closing Files
        .end:
            mov bx, [writingDescriptor]
            call procFClose
        
        .rasymoKlaida:
            mov bx, [readingDescriptor]
            call procFClose

        exit
        
%include 'yasmlib.asm'

; void procSkaitytiEilute()
; Read line to buffer ‘eilute’
procReadLine:
    push ax
    push bx
    push cx
    push si
    
    mov bx, [readingDescriptor]
    mov si, 0


    .loop:
        call procFGetChar
    
        ; End if the end of file or error
        cmp ax, 0
        je .endOfFile
        jc .endOfFile
        
        ; Putting symbol to buffer
        mov [line si], cl
        inc si
    
        ; Check if there is \n?
        cmp cl, 0x0A
        je .endOfLine
    
        jmp .loop
        
        
    .endOfFile:
        mov [readLastLine], byte 1
    .endOfLine:
    
    mov [line si], byte '$'
    mov [lineLength], si
    
    pop si
    pop cx
    pop bx
    pop ax
    ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

section .data

    readingFile:
        db 'input.dat', 00
        
    readingDescriptor:
        dw 0000
        
    writingFile:
        times 128 db 00
        
    writingDescriptor:
        dw 0000
        
    readLastLine:
        db 00
        
    line:
        db 64
        times 66 db '$'
        
    lineLength:
        dw 0000
    
    lineCount:
        times 128 db 00

My file:

XYZ;PPP;1;1;1;1.00
A11;bas aaa;0;0;5;1.15

My output: 4

Needed output: 2 (because there are only 2 "good" words "XYZ" and "PPP"), my program counts 2 more words because of a new line at the end.

CodePudding user response:

It would appear that in contrast with the original task description your file can contain one or more empty lines as well. Or even lines with spaces followed by the newline codes.
To deal with these empty lines (only containing the bytes 13 and 10), your idea to skip on codes below 32 is good, but it's in the wrong place.

Below is the quick fix. Please notice that the ASCII codes are to be treated as unsigned numbers. Don't use the signed jl instruction on them.

            mov  di, line
        .skipSpaces:
            mov  al, [di]
            inc  di
            cmp  al, ' '
            je   .skipSpaces
            cmp  al, ';'
            je   .q3
            dec  di
            cmp  al, 32         ; NEW
            jb  .skipLine       ; NEW
        .checkWord:
            mov  bx, 1
        .q1:
            mov  al, [di]
            inc  di
            cmp  al, ' '
            je   .q2
            cmp  al, ';'
            je   .q2
    !        cmp  al, 'A'
    !        jb   .q1
    !        cmp  al, 'K'
    !        jbe  .badChar    ; [A,K] is bad
    !        cmp  al, 'a'
    !        jb   .q1
    !        cmp  al, 'k'
    !        ja   .q1      
    !    .badChar:            ; [a,k] is bad
    !        mov  bx, 0       ; One or more invalid chars in current word
            jmp  .q1
        .q2:
            add  [lineCount], bx  ; BX=[0,1] Counting the 'good' words
            cmp  al, ';'
            jne  .skipSpaces
        .q3:
            dec  si          ; Next column?
            jnz  .skipSpaces
        .skipLine:
            cmp  [readLastLine], byte 0
            je   .whileNotTheEndOfFile

The lines that I marked with an exclamation mark really should be:

        or   al, 32      ; Make lowercase
        cmp  al, 'a'
        jb   .q1
        cmp  al, 'k'
        ja   .q1
        mov  bx, 0       ; [A,K] and [a,k] are badChars

Why does your program contain next redundant lines?

       ; Jeigu ne failo pabaiga, kartojame cikla
       .skipLine:
       sub [lineCount], 2
       cmp [readLastLine], byte 0
       je .whileNotTheEndOfFile
  • Related