2013-12-15 56 views
0

我正在尝试编写一个简单的程序,它从键盘接收字符串,然后将其打印到屏幕上。到目前为止,我无法让它工作。如何使用汇编语言从键盘读取输入字符串

下面的代码:

.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时,我得到you entered *gibberish*

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

我正在使用IA32指令集。

任何帮助将不胜感激。

+0

哪个操作系统,你的目标? – nrz

+0

linux Ubuntu 32bit –

+2

我没有看到你在哪里告诉'scanf'你想要它在哪里。 'leal -100(%ebp),%eax'和'pushl%eax'或者AT&T做的...... –

回答

1

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

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