如何使用汇编语言从键盘读取输入字符串

时间:2013-12-15 23:59:30

标签: linux assembly x86 printf scanf

我正在尝试编写一个简单的程序,从键盘中取出字符串,然后将其打印到屏幕上。到目前为止,我无法使其发挥作用。

以下是代码:

    .section .rodata
output: .string "you entered %s\n"
input:  .string "%s"

    .text
.globl  main
    .type   main, @function

main:
    pushl   %ebp
    movl    %esp, %ebp

    subl    $100, %esp
    pushl   $input
    call    scanf

    movl    %ebp, %esp
    subl    $100, %esp
    pushl   $output
    call    printf

    xorl    %eax, %eax
    movl    %ebp, %esp
    popl    %ebp
    ret

当我执行它时,对于任何给定的输入,输出为you entered (null)。 当我将subl $100, %esp命令的偏移量(call print之前的那个)设置为subl $104, %esp时,我得到you entered %s,当偏移量设置为108时,我得到{{1} }。

我觉得这是一个游戏,我需要猜测you entered *gibberish*在堆栈中保存字符串的位置(为什么它不应该在哪里?)。

我正在使用IA32指令集。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

基本上你的程序有3个问题:

subl    $100, %esp
pushl   $input
# Error 1:
# As Frank Kotler already wrote at this point
# only $input is stored on the stack; however
# the address of the buffer must also be on
# the stack (see Frank Kotler's comment)
call    scanf

movl    %ebp, %esp
# Error 2:
# Now the buffer is below ESP.
# Because interrupts use the kernel stack they
# will not overwrite the memory below ESP.
# However signals will destroy the memory below
# ESP!!
#
# Instead of the lines:
#   movl    %ebp, %esp
#   subl    $100, %esp
#
# You should use something like this:
#   add $8, %esp
# or:
#   lea -100(%ebp), %esp
#

subl    $100, %esp
# Error 3:
# As for "scanf" the second argument
# is missing on the stack
pushl   $output
call    printf