Question

I am using 64-bit linux and programming in assembler using gas. The issue I am having is I let the user enter lets say "1 + 12" using the system call read, and saving it as follows.

My read function:

    .type _read, @function
_read:
    pushq  %rbp                     # Save old base pointer
    movq   %rsp,%rbp

    movq   $200,%rdx                # MAX characters to retrieve
    movq   $equation,%rsi           # Buffer for equation string
    movq   $0,%rdi                  # STDIN
    movq   $0,%rax                  # SYS_READ
    syscall

    movq   %rbp,%rsp                # Restore base pointer
    popq   %rbp
    ret                             # Return from function

equation is declared as:

.section .bss
.lcomm equation, 200

So I parse through each byte of equation trying to save the numbers, but if they enter "12" than I would first get 1 and than 2, I need to somehow save 12 on the stack and be able to just popq %rax and have "12" in there. I am not sure how to go about this? Any input would be greatly appreciated.

Was it helpful?

Solution

You'll have to write some sort of parser. Here's an example (I'm using 16-bit assembly in Intel syntax, but you get the gist of it):

; Parses the zero-terminated string 'equation', converts any numbers
; found in that string from strings to integers and pushes them on
; the stack.
parse_equation:
  pop di        ; pop the return address
  lea si,[equation]
  cld
  xor cl,cl     ; # of chars in the currently parsed number
skip_non_number:
  lodsb
  test al,al
  jz end_of_equation
  cmp al,'0'
  jb skip_non_number
  cmp al,'9'
  ja skip_non_number
  sub al,'0'        ; convert '0'..'9' -> 0..9
  movzx bx,al       ; zero-extend to word and store in bx
parse_number:
  inc cl
  lodsb
  test al,al
  jz end_of_equation
  cmp al,'0'
  jb end_of_number
  cmp al,'9'
  ja end_of_number
  sub al,'0'
  mov ch,al
  mov ax,10
  mul bx        
  movzx bx,ch
  add bx,ax     ; bx = bx*10 + (word)al
  jmp parse_number
end_of_number:
  push bx       ; store the parsed number on the stack
  xor cl,cl
  jmp skip_non_number   ; start over again
end_of_equation:
  test cl,cl
  jz nothing_to_push
  push bx       ; the string ended with a number; push it
nothing_to_push:
  jmp di        ; return


My code ignores anything that isn't a number (like arithmetic operators), and doesn't handle signed numbers. I'll leave it to you to figure out how to handle such things.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top