Search code examples
linuxassemblyx86att

compare number and variable in assemblyx86


This code reads data from an inputfile character by character and it writes to another file. It should stop to read and write once it finds a character with value equal to 3. I said should because the program doesn't stop once it finds a value equal to 3, instead it continues to read until the end of file.

Inputfile is like: 2 4 5 3 1 8

My code is:

.section .data

  varInputHandle: .long 100
  varOutputHandle: .long 100
  varExitCode: .long 1
  cont: .long 1
.section .bss
  .lcomm varBuffer, 1        

.section  .text              # declaring our .text segment
  .globl _start              # telling where program execution should start

_start:

    popl %eax       # Get the number of arguments
    popl %ebx       # Get the program name

    # open input file first 
    popl %ebx       # Get the first actual argument - file to read
    movl $5, %eax       # open
    movl $0, %ecx       # read-only mode
    int $0x80
    movl %eax, varInputHandle   #store input file handle to memory

    #open output file, make it writable, create if not exists
    popl %ebx           # Get the second actual argument - file to write
    movl $5, %eax       # open 
    movl $0101, %ecx    # create flag + write only access (if google is telling me truth)
    movl $0666, %edx    #permissions for out file as rw-rw-rw-
    int $0x80
        movl %eax, varOutputHandle #store output file handle to memory

contToZero:
movl $0, cont
processingLoop:
    incb cont
    #read single char to varBuffer
    movl $3, %eax
    movl varInputHandle, %ebx
    movl $varBuffer, %ecx
    movl $1, %edx
    int $0x80

    #if no char was read (EOF?), jmp finishProcessing
    cmpl $0, %eax
    jz finishProcessing # looks like total success, finish cleanly

    cmpl $3, varBuffer   // this instruction is never true, don't know why
    je exitToOs
    #write it
    movl $4, %eax       
    movl varOutputHandle, %ebx     # file_descriptor
    movl $varBuffer, %ecx  
    movl $1, %edx
    int $0x80

    # done, go for the next char
    goForTheNextChar:
    jmp processingLoop

finishProcessing:
    movl $0, varExitCode #everything went OK, set exit code to 0

exitToOs:
    movl varOutputHandle, %ebx     # file_descriptor
    movl varInputHandle, %ebx    
    movl $1, %eax
    movl varExitCode, %ebx
    int $0x80

closeFile:
    cmpl $-1, %ebx
    movl $6, %eax  #sys_close
    int $0x80

cmpl $3, varBuffer seems to never be true therefore I can't jump to exitToOs.


Solution

  • In your code you have:

     cmpl $3, varBuffer
    

    This can never be true because you do not have binary data in your file.

    When you read character by character, you are reading ASCII values. In order to properly make this comparison you must do one of two things:

    1. Convert the character read from ASCII to decimal
    2. Compare the read value to an ASCII value

    Since you are relying on $0 to identify when you have read zero bytes, I would suggest that you take the (easier) approach of checking for the ASCII value that you would like to find. In your case this would be:

     cmpb $'3', varBuffer     # Compare character to 0x33 / 51 / "3"