4

This is, hopefully, a simple question:

First, I would like to know if anyone has an idea of how to get user input using x86 NASM Syntax Assembly on Linux. Right now, I have:

section .data
    greet:       db 'Hello!', 0Ah, 'What is your name?', 0Ah  ;simple greeting
    greetL:      equ $-greet                                  ;greet length
    colorQ:      db 'What is your favorite color?'            ;color question
    colorL:      equ $-colorQ                                 ;colorQ length
    suprise1:    db 'No way '                               
    suprise1L    equ $-suprise1
    suprise3:    db ' is my favorite color, too!', 0Ah

section .bss 
    name:        resb 20                                      ;user's name
    color:       resb 15                                      ;user's color

section .text
    global _start
_start:

    greeting:
         mov eax, 4
         mov ebx, 1
         mov ecx, greet
         mov edx, greetL
         int 80                                               ;print greet

    getname:
         mov eax, 3
         mov ebx, 0
         mov ecx, name
         mov edx, 20
         int 80                                               ;get name

    askcolor:
         ;asks the user's favorite color using colorQ

    getcolor: 
         mov eax, 3
         mov ebx, 0
         mov ecx, name
         mov edx, 20
         int 80

    thesuprise:
         mov eax, 4
         mov ebx, 1
         mov ecx, suprise1
         mov edx, suprise1L
         int 80 

         mov eax, 4
         mov ebx, 1
         mov ecx, name
         mov edx, 20
         int 80 

         ;write the color

         ;write the "suprise" 3

         mov eax, 1
         mov ebx, 0
         int 80

So what it does is ask for a name and color, and say, "No way --name-- --color-- is my favorite color, too.

What I need help on is how to find how long the "name" and "color" variables above are after the user enters them. Otherwise, I get a bunch of long, nasty spaces in between because I only know that the max size they can be is what I declared before.

Thank you for any and all help.

nmagerko
  • 6,586
  • 12
  • 46
  • 71
  • `int 80` is `int 0x50`. You want `int 0x80`. (possible canonical duplicate for that: [Assembler sysTime giving error on executing](https://stackoverflow.com/a/39412096)) – Peter Cordes Jul 28 '21 at 22:07

3 Answers3

2

The read system call returns the number of bytes read in the eax register. If this number is < 0, there was a read error of some sort.

Callum
  • 862
  • 5
  • 13
  • I have tried to use the value "returned" in eax after the read instruction, but this does nothing but return how much I originally declared the buffer to be – nmagerko Oct 19 '11 at 21:12
1

I know this is quite old but for anyone in the future looking at this, there is another way to accomplish what the OP is asking for, with basically 1 line. It may not be ideal, but for something like this, it should work fine. Basically, instead of trying to figure out the length of the word that the user input, lets just assume that theyre going to input something like 'RED' or 'ORANGE', etc.. no fancy colors.. So lets assume that the longest color would be like 8 characters. That being said, we can do the following.

.bss 
     color:     resb     8

Again, its not ideal but it does work and in this case, a few extra bytes shouldnt effect it too much.

Brad Bass
  • 361
  • 1
  • 4
  • 15
1

You will be calling read in a loop.

The easiest way, although not the best, is to read one byte at a time looking for LF (byte 10).

Joshua
  • 40,822
  • 8
  • 72
  • 132
  • Please elaborate. I understand how to read user input, but how could I store the input a byte at a time if I do not know how long it will be? Also, how could I compare byte 10 to a character without some sort of string to integer method? – nmagerko Oct 16 '11 at 22:53
  • bytes are very short integers. – Joshua Oct 17 '11 at 13:47
  • I normally declare a buffer of length 80 and complain if the users exceeds it. – Joshua Oct 17 '11 at 13:47
  • Reading one character at a time requires disabling canonization (buffering of characters until return is pressed). That is of course doable, but not exacly easy. – Fabel Oct 17 '11 at 18:37
  • Wait, what? It's the equivalent to calling getc(stdin) in a loop without buffering in userspace. – Joshua Oct 17 '11 at 20:23