做CSAPP遇到點問題,希望能指點一番?
。-------------------------------------------
Dump of assembler code for function phase_2: 0x0000000000400efc &<+0&>: push %rbp 0x0000000000400efd &<+1&>: push %rbx 0x0000000000400efe &<+2&>: sub $0x28,%rsp0x0000000000400f02 &<+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 0x400f250x0000000000400f20 &<+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 %rbx0x0000000000400f41 &<+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???
推薦閱讀: