Domanda

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.

È stato utile?

Soluzione

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top