Search code examples
filehttp-redirectassemblyinputyasm

yasm multiple arbitrary inputs not working when redirecing inputs from a file


I am a student and I am struggling a bit with assembly.

I have to make a basic calculator that can take in 2 64-bit arbitrary integers as input and a 8-bit char.

From these inputs I need to use the char to determine what operation should take place. Addition, multiplication, subtraction, or division.

The University tests our programs using a program that runs our program by redirecting the inputs from a predetermined file; to compare our output with the expected output. We do not get any feedback from this program, just a mark.

My code works when implementing it in the console, but not when redirecting the input from a file like their program would.

Here is the "faulty part" of my code:

_start:
mov rax, 1          ;Write
mov rdi, 1          ;Std out
mov rsi, request1   ;Address of message.    Asks for first input
mov rdx, 24         ;Length of message
syscall             ;Calls kernel

mov rax, 0          ;Read
mov rdi, 0          ;Std in
mov rsi, input1     ;Address of variable.   Largest 64-bit int is 19
mov rdx, 20         ;Max length of input.   digits long + newline
syscall             ;Calls kernel

mov rax, 1          ; Another Write. Asks for operand
mov rdi, 1
mov rsi, input1
mov rdx, 20
syscall

mov rax, 0          ;Another Read. Gets operand + newline
mov rdi, 0
mov rsi, operand
mov rdx, 2
syscall

mov rax, 1          ;Another Write., Asks for second input
mov rdi, 1
mov rsi, request3
mov rdx, 25
syscall

mov rax, 0          ;Another Read. Caters for a 64-bit number
mov rdi, 0
mov rsi, input2
mov rdx, 20
syscall

For example lets say my input file has the following:

10000000000
+
101010101

I redirect the input of my program using the command:

./program < inputfile

My program then reads the data into the variables as follows:

Input1 : 10000000000\n+\n101010
operand: 10
Input2 : 1

How can I make the program stop reading on the newline char? Or how can I work around this problem?

I tried reading the inputs digit for digit, but I didn't get vary far before I got stuck.


Solution

  • Run strace ./myprogram. A read() system call doesn't end at a newline if there's more data available on that file descriptor, which is the case when you redirect.

    Pressing return interactively "submits" the line and makes it possible for read() to return early (before reading the full 20 bytes you passed as a size).

    So your current program depends on POSIX TTY behaviour.


    The fix: parse the string instead of depending on separate writes. You can look for the '\n' characters that separate input lines.