深入理解計算機第三章筆記

深入理解計算機第三章筆記

1
2
3
4
5
6
7
multstore:
pushq %rbx
movq %rdx,%rbx
call mult2
movq %rax,(%rbx)
popq %rbx
ret

匯編代碼解釋
pushq %rbx將寄存器rbx的內容放入程序棧

objdump -d mstore.o
可查看機械代碼文件內容

代碼範例2

1
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]表示對儲存在內存裡面。

操作數的各種尋址模式

adress.jpg

練習題3.1

exercise.jpg

答案
|操作數|值|解釋|
|:——|:——|:——|
|%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
4
movabsq $0x001122334455677,%rax   %rax = 0011223344556677
movb $0xAA,%dl %dl = AA
movb $dl,%al %rax = 00112233445566AA
movsbq $dl,%rax %rax = FFFFFFFFFFFFFFAA

0%