从堆栈读取多个字节到单个寄存器

时间:2013-08-29 03:44:56

标签: linux assembly gas

我正在使用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”。我不知道怎么回事?任何意见都将不胜感激。

1 个答案:

答案 0 :(得分:0)

你必须编写某种解析器。这是一个例子(我在英特尔语法中使用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


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