【问题标题】:Read Multiple bytes from stack into single register将堆栈中的多个字节读入单个寄存器
【发布时间】:2013-08-29 03:44:55
【问题描述】:

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

【问题讨论】:

    标签: linux assembly gnu-assembler


    【解决方案1】:

    您必须编写某种解析器。这是一个示例(我在 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
    


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

    【讨论】:

    • 您好,感谢您的代码!我可能没有完全清楚地解释自己(对此感到抱歉)我已经有一个函数来解析字符串的每个字节,如果用户键入 12,我可以获得“1”和 2,但我只是不确定如何将其存储到一个寄存器中,以便我可以使用它来添加、div 等...或者我是否错过了在您的代码中的某个地方看到它?如果我这样做了,请道歉。
    • 好吧,如果你为我的解析例程提供了字符串"123 + 45",它会将(16位)整数12345压入堆栈,这听起来像你想要的(除了你使用的是 64 位寄存器,但想法是一样的)。
    • 哦,是的,我忽略了方程式部分。 "; bx = bx*10 + (word)al" 真的很有用。谢谢。
    猜你喜欢
    • 2012-04-27
    • 2016-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    • 1970-01-01
    • 2017-01-25
    相关资源
    最近更新 更多