问题描述
通读《专业汇编语言书》;似乎它为读取命令行参数提供了错误的代码.我进行了一些更正,现在它从段错误变为读取参数计数再到段错误.
Reading through the "Professional Assembly Language Book"; it seems that it provides an erroneous code for reading command-line arguments. I corrected it a bit and now it went from segfaulting to reading argument count then segfaulting.
这是完整的代码:
.data
output1:
.asciz "There are %d params:\n"
output2:
.asciz "%s\n"
.text
.globl main
main:
movl 4(%esp), %ecx /* Get argument count. */
pushl %ecx
pushl $output1
call printf
addl $4, %esp /* remove output1 */
/* ECX was corrupted by the printf call,
pop it off the stack so that we get it's original
value. */
popl %ecx
/* We don't want to corrupt the stack pointer
as we move ebp to point to the next command-line
argument. */
movl %esp, %ebp
/* Remove argument count from EBP. */
addl $4, %ebp
pr_arg:
pushl (%ebp)
pushl $output2
call printf
addl $8, %esp /* remove output2 and current argument. */
addl $4, %ebp /* Jump to next argument. */
loop pr_arg
/* Done. */
pushl $0
call exit
书中的代码:
.section .data
output1:
.asciz "There are %d parameters:\n"
output2:
.asciz "%s\n"
.section .text
.globl _start
_start:
movl (%esp), %ecx
pushl %ecx
pushl $output1
call printf
addl $4, %esp
popl %ecx
movl %esp, %ebp
addl $4, %ebp
loop1:
pushl %ecx
pushl (%ebp)
pushl $output2
call printf
addl $8, %esp
popl %ecx
addl $4, %ebp
loop loop1
pushl $0
call exit
用GCC(gcc cmd.S
)编译,也许是问题所在? __libc_start_main是否以某种方式修改了堆栈?不太确定...
Compiled it with GCC (gcc cmd.S
), maybe that's the problem? __libc_start_main modifies the stack in some way? Not quite sure...
更糟糕的是,尝试对其进行调试以查看堆栈,但是GDB似乎抛出了许多与printf相关的东西(其中之一是printf.c: File not found
或类似的东西).
Even worse, trying to debug it to look at the stack but GDB seems to throw a lot of printf-related stuff (one of them was printf.c: File not found
or something similar).
推荐答案
在@Michael的帮助下,我能够找到问题所在.
With the help from @Michael, I was able to track down the problem.
按照@Michael的建议,将%ebp用作argv
(尽管他使用了%eax
).另一个问题是我需要将(%ebp)的值与0(空终止符)进行比较,然后在该点结束程序.
Using %ebp as argv
as @Michael suggested (he used %eax
though). Another problem was that I needed to compare the value of (%ebp) with 0 (the null terminator) and end the program at that point.
代码:
movl 8(%esp), %ebp /* Get argv. */
pr_arg:
cmpl $0, (%ebp)
je endit
pushl %ecx
pushl (%ebp)
pushl $output2
call printf
addl $8, %esp /* remove output2 and current argument. */
addl $4, %ebp
popl %ecx
loop pr_arg
ret
这篇关于从汇编程序获取命令行参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!