1

我正在使用 64 位 linux 并使用 gas 在汇编程序中编程。我遇到的问题是我让用户输入让我们使用系统调用读取说“1 + 12”,并将其保存如下。

我的阅读功能:

    .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

方程被声明为:

.section .bss
.lcomm equation, 200

所以我解析方程的每个字节试图保存数字,但如果他们输入“12”而不是我首先得到 1 和 2,我需要以某种方式将 12 保存在堆栈上,并且能够仅 popq %rax 并拥有“12”在那里。我不知道该怎么做?任何投入将不胜感激。

4

1 回答 1

0

您必须编写某种解析器。这是一个示例(我在 Intel 语法中使用 16 位汇编,但您明白了它的要点):

; 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


我的代码忽略了任何不是数字的东西(比如算术运算符),并且不处理有符号的数字。我会留给你弄清楚如何处理这些事情。

于 2013-08-29T06:31:24.040 回答