深入理解計算機第三章筆記1
2
3
4
5
6
7multstore:
pushq %rbx
movq %rdx,%rbx
call mult2
movq %rax,(%rbx)
popq %rbx
ret
匯編代碼解釋pushq %rbx
將寄存器rbx的內容放入程序棧
objdump -d mstore.o
可查看機械代碼文件內容
代碼範例21
2
3
4
5
6
7
8
9
10
11
12
13#include <stdio.h>
void multstore(long,long,long *);
int main(){
long d;
mulrstore(2,3, %d);
printf("2 *3 --> %ld\n",d);
return 0;
}
long mult2(long a,long b){
long s = a * b;
return s;
}
gcc -Og -o prog main.c mstore.c
2大規則For生成小於8字節結果的指令:
生成1字節和2字節的指令會保持,剩下的字節不會改變。
生成4字節數字的指令會把高位4個字節變0.
RSP - 指明棧運行時結束位置。
操作數
1.立即數(Immediate) - $ + 整數 例子$-577 /$0x1F等等
2.寄存器 - RAX,RBX,RCX…RIP等等 ra表示任意寄存器a,而R[ra]表示它的值,看成一個數組R,用寄存器標識符作為索引。
3.內存引用 - 用Mb[Addr]表示對儲存在內存裡面。
操作數的各種尋址模式
練習題3.1
答案
|操作數|值|解釋|
|:——|:——|:——|
|%rax|0x100|寄存器|
|0x104|0xAB|絕對地址|
|$0x108|0x108|立即數|
|(%rax)|0xFF|間接尋址:因為這裡說的是去尋找0x100地址的值|
|4(%rax)|0xAB|間接尋址:因為這裡說的是去尋找0x104地址的值|
|9(%rax,%rdx)|0x11|0100+0003+0009=0x10C,答案為地址0x10C的值|
|260(%rcx,%rdx)|0x13|0001+0003+0104=0x108,答案為地址0x108的值,260要轉成16進制才可以進行運算|
|0xFC(,%rcx,4)|0xFF|0004+00FC=0xFF, 0004是0001經過比例4後變成的|
|(%rax,%rdx,4)|0x11|000C+0100=0x10C,000C是0003經過比例4=>3x4=12=C變成的|
數據傳輸指令
mov S,D- 把數據從源位置S傳送到目標位置D。
- movb 傳送字節
- movw 傳送字
- movl 傳送雙字
- movq 傳送四字
- movabsq 傳送絕對四字 [以任意64位作為立即數,但目標對象只能是寄存器]
Mov傳輸的方式
- movl $0x4050,%EAX Immediate to Register 4 bytes
- movw %bp,%sp Register to Register 2 bytes
- movb (%rdi,%rcx),%al Memory to Register 1 byte
- movb $-17,(%rsp) Immediate to Memory 1 byte
- movq %rax,-12(%rbp) Register to Memory 8 bytes
1.將較小的源值複製到較大的目的時使用MOVZ或MOVS。
2.MOVZ把目的中的字節填0
3.MOVS把指令通過符號擴展來填充,同時把源操作的最高位進行複製
4.每個指令最後2個字符是大小指示符號。第一個指定源的大小,後者指定第二個明目的大小
- movzbw 零擴展字節傳送到字
- movzbl 零擴展字節傳送到雙字
- movzwl 零擴展字傳送到雙字
- movzbq 零擴展字節傳送到四字
- movzwq 零擴展字傳送到四字
【上述指令以內存地址為來源,以寄存器作為目的】
- movsbw 將做了符號擴展的字節傳送到字
- movsbl 將做了符號擴展的字節傳送到雙字
- movswl 將做了符號擴展的字傳送到雙字
- movsbq 將做了符號擴展的字節傳送到四字
- movswq 將做了符號擴展的字傳送到四字
- movslq 將做了符號擴展的雙子傳送到四字
- cltq 把%eax符號擴展到%rax [只作用在這2個寄存器]
MOV使用例子
movabsq $0x0011223344556677,%rax %rax=0011223344556677
movb $-1,%al %rax=00112233445566FF
movw $-1,%ax %rax=001122334455FFFF
movl $-1,%eax %rax=00000000FFFFFFFF
movq $-1,%rax %rax=FFFFFFFFFFFFFFFF
練習3.2
movl %eax,(%rsp) 雙字,因為EAX是32位元(雙字)寄存器
movw (%rax),%dx 字,因為dx是16位元寄存器
movb $0XFF,%bl 字節,因為bl是8位元寄存器
movb (%rsp,%rdx,4).%dl 字節,因為dl是8位元寄存器
movq (%rdx),(%rax) 四字,因為RAX為64位元寄存器
movw %dx,(%rax) 字,因為dx是16位元寄存器
例子2
下面是movb,movsbq和movzbq在傳送上改變/不改變高字節的差別1
2
3
4movabsq $0x001122334455677,%rax %rax = 0011223344556677
movb $0xAA,%dl %dl = AA
movb $dl,%al %rax = 00112233445566AA
movsbq $dl,%rax %rax = FFFFFFFFFFFFFFAA