2013-11-02 150 views
4

我知道我要說的這句話可能是非常快速地在StackOverflow上變得非常不受歡迎的最好方法。無論如何,我會這樣說:爲什麼這不工作(完全)?IA32程序集:lea指令

我試圖弄清楚lea/leal指令的作用是什麼。按照我的理解,lea/leal找出第一個操作數的內存地址,並將此地址寫入第二個操作數(可能是一個寄存器或其他地址)。

這部分似乎工作。當我運行下面的程序時,它說:

The memory address of var is 134518204. 

但是,在此之後它說「內存訪問錯誤」之類的東西。 pushl(%eax)顯然不起作用。爲什麼不?

.data 
    var: .long 42 
    str1: .string "The memory address of var is %d.\n" 
    str2: .string "At this memory address we find var's value: %d.\n" 

.text 
.global main 
main: 
    leal var, %eax   # Copy the address of var into %eax 
    pushl %eax 
    pushl $str1 
    call printf    # Print str1 
    pushl (%eax) 
    pushl $str2 
    call printf    # Print str2 

    # Some stack cleaning should be here :) 

    movl $1, %eax 
    int $0x80 

我甚至不確定我是否正確地使用了哪些文件。幫助表示讚賞。 ;)

+1

'movl src,dest'表示'dest = src'。 ''leal src,dest''表示'dest =&src'(即dest = src的地址) – Sam

+0

爲了更加準確,movl會評估源,將其視爲地址並將其內容移至目的地。 但是,'leal'評估來源並將評估值移到目的地。 – Sam

+0

[LEA指令的目的是什麼?](http://stackoverflow.com/questions/1658294/whats-the-purpose-of-the-lea-instruction) –

回答

2

我明白它的方式,lea/leal找出第一個操作數的內存地址,並將這個地址寫入第二個操作數(可能是一個寄存器左右)。

聽起來足夠準確。它用於執行地址算術;這可以像加載地址一樣簡單,但您也可以使用它來執行某些常量的乘法運算。


pushl (%eax)顯然是行不通的。爲什麼不?

push指令沒有引用您認爲它的地址:printf返回寫入的字符數,和值在%eax寄存器返回,所以%eax不再包含的var地址。

+0

非常感謝!我實際上剛剛根據C調用公約閱讀,%eax將始終被更改。似乎我真的需要做一些其他的一些事情......:D – lambdarookie

2

lea通常用於計算:如果您只想在寄存器中使用全局地址,movl $var, %eaxlea更清晰(且字節更短)。

另外,要說清楚,lea的目標操作數必須是是寄存器。

+0

非常感謝,這也非常有幫助! – lambdarookie