2015-04-21 26 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