2015-04-21 27 views
1

好吧,这可能是一个愚蠢的问题,但我想我和其他人可能在学习的过程:从非x4地址访问堆栈 - 有可能吗?

我与32位汇编工作,并在& T语法。

假设我想dinamically生成一个字符串,保存它的内容到堆栈:

.data 
str: .long 0 
string: .string "value is %s.\n" 
.globl main 

movb $0,str+3 #terminate the string 
movb $67,str+2 
movb $67,str+1 
pushl $str 
movl %esp,%eax 
incl %eax 
push (%eax) 
push $string 
call printf 
addl $12,%esp 
ret 

一点也没有“T工作,我得到一个分段错误。但是,如果我评论的线

# incl %eax 

,并在海峡开始添加另一个字节:

movb $67,str 

然后它完美的作品,并显示CCC。

看来,我不能引用从不是4的倍数的地址开始的字符串。或者我错了吗?我知道我可以从任何地址引用变量,但有没有办法在堆栈中这样做?

回答

2

你可以,但你做错了。您将字符串的地址放在堆栈上,然后尝试增加地址的地址并将其解引用。你想增加地址。使用incl (%eax)增加堆栈上的地址应该可以工作。然而整个事情是过于复杂,你可以简单地做push $str+1

movb $0,str+3 #terminate the string 
movb $67,str+2 
movb $67,str+1 
pushl $str+1 
push $string 
call printf 
addl $8,%esp 
ret 

您可以访问堆栈对齐的,但你应该确保它是有道理的。由于堆栈中有4个字节的地址,如果你访问那个未对齐的地址,你将得到3个字节的数据,而另一个字节则来自堆栈中的下一个项目,不管它是什么。这当然不太可能是有效的地址,因此是段错误。这个错误并不是用来访问堆栈未对齐的,这是因为你解除了一个无效指针的引用。

+0

再次感谢@Jester!它非常完美! :d – francisaugusto