做CSAPP遇到點問題,希望能指點一番?

。-------------------------------------------

Dump of assembler code for function phase_2:

0x0000000000400efc &<+0&>: push %rbp

0x0000000000400efd &<+1&>: push %rbx

0x0000000000400efe &<+2&>: sub $0x28,%rsp

0x0000000000400f02 &<+6&>: mov %rsp,%rsi

=&> 0x0000000000400f05 &<+9&>: callq 0x40145c

0x0000000000400f0a &<+14&>: cmpl $0x1,(%rsp)

0x0000000000400f0e &<+18&>: je 0x400f30

0x0000000000400f10 &<+20&>: callq 0x40143a

0x0000000000400f15 &<+25&>: jmp 0x400f30

0x0000000000400f17 &<+27&>: mov -0x4(%rbx),%eax

0x0000000000400f1a &<+30&>: add %eax,%eax

0x0000000000400f1c &<+32&>: cmp %eax,(%rbx)

0x0000000000400f1e &<+34&>: je 0x400f25

0x0000000000400f20 &<+36&>: callq 0x40143a

0x0000000000400f25 &<+41&>: add $0x4,%rbx

0x0000000000400f29 &<+45&>: cmp %rbp,%rbx

0x0000000000400f2c &<+48&>: jne 0x400f17

0x0000000000400f2e &<+50&>: jmp 0x400f3c

0x0000000000400f30 &<+52&>: lea 0x4(%rsp),%rbx

0x0000000000400f35 &<+57&>: lea 0x18(%rsp),%rbp

0x0000000000400f3a &<+62&>: jmp 0x400f17

0x0000000000400f3c &<+64&>: add $0x28,%rsp

0x0000000000400f40 &<+68&>: pop %rbx

0x0000000000400f41 &<+69&>: pop %rbp

0x0000000000400f42 &<+70&>: retq

-------------------------------------

這個第22行和第23行,兩句lea是什麼意思?還有,第13行,mov -0x4(%rbx),%eax不太理解,是指針的地址還是,謝謝, 我的思路是,在0x0000000000400f0a &<+14&>: cmpl $0x1,(%rsp),這一行我們可以確定%rsp為1,然後跳到0x0000000000400f30 &<+52&>: lea 0x4(%rsp),%rbx,是把%rbx = 0x1 + 0x4 = 0x5, 0x0000000000400f35 &<+57&>: lea 0x18(%rsp),%rbp,意思是%rbp = 0x1 + 0x18 = 0x19,十進位為25,然後r跳到0x0000000000400f17 &<+27&>: mov -0x4(%rbx),%eax,這一行,%eax = 0x5 - 0x4 = 0x1 ???,然後%eax 相當於乘以2 ,等於2,與%rbx 比較,所以%rbx = 2 ???,然後調到 0x0000000000400f25 &<+41&>: add $0x4,%rbx,%rbx = 0x5 + 0x4 = 0x9,不等於%rbp = 25,然後繼續跳到 0x0000000000400f17 &<+27&>: mov -0x4(%rbx),%eax???


謝邀。

這是IA32。

lea S D的效果是把S的地址複製給目標寄存器D的值。

0x4(%rsp)代表的是一個地址值,值是0x4加上寄存器%rsp中的值。

lea 0x4(%rsp),%rbx 的效果就是把寄存器%rsp中的值加上0x4然後賦給%rbx。

mov -0x4(%rbx),%eax 就是把內存中地址為%rbx減去0x4位置上的值賦給%eax 。


看ATT語法的彙編真是頭大到爆炸……寫起來也一樣……

所以還是只說幾句不貼代碼了吧,lea這條指令的名字容易理解錯誤,這句指令其實跟內存無關。只是一個便於用來計算內存地址(指針)的數學指令。他計算源操作數中地址的disp+base+index*scale並將計算的結果寫入目標操作數,期間不會訪問任何內存。

而mov,則是在計算出上一步提到的結果時,去那個地址所指向的內存讀取數據並寫入目標操作數,所以是會訪問內存的。

lea經常會被用於一些簡易的數學運算,比如說題目中的對一個操作數加4,在這種情況下,這條指令的作用跟他的名字就更沒啥關係了。不過這種用法很常見,比如說設源操作數的base為eax、index為eax、scale為2、disp為0,目標操作數為ecx,就可以簡單的在ecx中得到三倍的eax,相當於一個乘法,因為x86架構費勁的乘法運算,這種寫法經常可以看到。


lea指令(Load effect address), 操作的是內存地址!!!

mov指令(Move), 操作的是存放在內存地址中的值!!!

lea 0x4(%rsp),%rbx %rsp的值加上0x4作為內存地址, 存放到%rbx

mov -0x4(%rbx),%eax %rbx的值減去0x4作為內存地址, 把該內存地址中的值, 存放到%eax


你malloc寫好了嗎


@白如冰謝謝

謝謝冰神。不是,我的思路是,在0x0000000000400f0a &<+14&>: cmpl $0x1,(%rsp),這一行我們可以確定%rsp為1,然後跳到0x0000000000400f30 &<+52&>: lea 0x4(%rsp),%rbx,是把%rbx = 0x1 + 0x4 = 0x5, 0x0000000000400f35 &<+57&>: lea 0x18(%rsp),%rbp,意思是%rbp = 0x1 + 0x18 = 0x19,十進位為25,然後r跳到0x0000000000400f17 &<+27&>: mov -0x4(%rbx),%eax,這一行,%eax = 0x5 - 0x4 = 0x1 ???,然後%eax 相當於乘以2 ,等於2,與%rbx 比較,所以%rbx = 2 ???,然後調到 0x0000000000400f25 &<+41&>: add $0x4,%rbx,%rbx = 0x5 + 0x4 = 0x9,不等於%rbp = 25,然後繼續跳到 0x0000000000400f17 &<+27&>: mov -0x4(%rbx),%eax???


推薦閱讀:

如何取得32位無符號數二進位表示是否含有奇數個1?

TAG:編程 | 計算機科學 | 計算機組成原理 | CSAPP |