•三種尋址方式:當即數尋址、寄存器尋址方式、存儲器尋址方式尋址方式。html
•浮點數主要有兩種形式:單精度(4字節)值,對應於C語言數據類型float;雙精度(8字節)值,對英語C語言數據類型double。數組
•經常使用條件碼:CF:進位標誌。ZF:零標誌。SF:符號標誌。OF:溢出標誌。安全
•CMP指令根據他們的兩個操做數之差來設置條件碼。除了只設置條件碼而不更新目標寄存器以外,CMP與SUB行爲是同樣的。bash
•操做系統負責管理虛擬地址空間,將虛擬地址翻譯成實際處理器存儲器中的物理地址。函數
•程序寄存器組是惟一能被全部過程共享的資源。慣例是爲了防止一個過程P調用另外一個過程Q時寄存器中的值被覆蓋保存某值的兩種方式學習
①由調用者保存。在調用以前就壓進棧。操作系統
②由被調用者保存,在剛被調用的時候就壓進棧,並在返回以前恢復。翻譯
•操做數的三種類型:當即數、寄存器、存儲器設計
•棧:「後進先出」,棧頂元素的地址是全部棧中元素地址中最低的。指針
•有效地址的計算方式 Imm(Eb,Ei,s) = Imm + R[Eb] + R[Ei]*s
•MOV至關於C語言的賦值 「=」 (注意不能從內存地址直接MOV到另外一個內存地址,要用寄存器中轉一下)
•移位操做中移位量能夠是當即數或%cl中的數
•leal不改變條件碼寄存器
•SET指令根據t=a-b的結果設置條件碼
•call/ret; 函數返回值存在%eax中
•寄存器使用慣例
程序寄存器組是惟一能被全部函數共享的資源。
雖然在給定時刻只能有一個函數是活動的,可是咱們必須保證當一個函數調用另外一個函數時,被調用者不會覆蓋某個調用者稍後會用到的值。爲此,IA32採用了一組統一的寄存器使用規則,全部的函數都必須遵照,包括程序庫中的函數。
根據慣例:寄存器%eax、%edx、%ecx被劃分爲調用者保存寄存器。當過程P調用Q時,Q能夠覆蓋這些寄存器,不會破壞任何P所須要的數據。
另外一方面,寄存器%ebx、%esi、%edi被劃分爲被調用者寄存器。這意味着Q必須在覆蓋這些寄存器的值以前,先把它們保存到棧中,並在返回前恢復它們。此外還必須保持寄存器%ebp和%esp。
•轉移控制
call Label 過程調用
call *Operand 過程調用
leave 爲返回準備棧
ret 從過程調用中返回
call指令的效果是將返回地址入棧,並跳轉到被調用過程的起始處。(返回地址是在程序正文中緊跟在call後面的那條指令的地址,這樣當被調用過程返回時,執行流會今後處繼續。)
ret指令從棧中彈出地址,並跳轉到這個位置。(使用這條指令前,要使棧作好準備,棧頂指針要指向前面call指令存儲返回地址的位置)
leave指令 使棧作好返回的準備。它等價於:
movl %ebp, %esp ; 把寄存器%ebp中的值複製到寄存器%esp中(回收本函數的棧空間)
popl %ebp
leave指令的使用在返回前,既重置了棧指針,也重置了基址指針。
使用fork,exec,wait實現mybash
一、fork函數
定義和理解:fork()函數經過系統調用建立一個與原來進程幾乎徹底相同的進程,也就是兩個進程能夠作徹底相同的事,但若是初始參數或者傳入的變量不一樣,兩個進程也能夠作不一樣的事。
一個進程調用fork()函數後,系統先給新的進程分配資源,例如存儲數據和代碼的空間。而後把原來的進程的全部值都複製到新的新進程中,只有少數值與原來的進程的值不一樣。至關於克隆了一個本身。
代碼以下:
#include <unistd.h> #include <stdio.h> int main(void) { int i=0; printf("i son/pa ppid pid fpid/n"); //ppid指當前進程的父進程pid //pid指當前進程的pid, //fpid指fork返回給當前進程的值 for(i=0;i<2;i++){ pid_t fpid=fork(); if(fpid==0) printf("%d child %4d %4d %4d/n",i,getppid(),getpid(),fpid); else printf("%d parent %4d %4d %4d/n",i,getppid(),getpid(),fpid); } return 0; }
exec函數族使用注意點:
在使用exec函數族時,必定要加上錯誤判斷語句。由於exec很容易執行失敗,其中最多見的緣由有:
① 找不到文件或路徑,此時errno被設置爲ENOENT。
② 數組argv和envp忘記用NULL結束,此時errno被設置爲EFAULT。
③ 沒有對應可執行文件的運行權限,此時errno被設置爲EACCES。
產品代碼:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #define MAXARGS 20 #define ARGLEN 100 int mybash20155310(char *arglist[]) { int pc,pr; pc=fork(); pr=wait(NULL); if(pc==0) execute(arglist); else return 0; } int execute(char *arglist[]) { execvp(arglist[0],arglist); perror("execvp failed"); exit(1); } char *makestring(char *buf) { char *cp; buf[strlen(buf)-1] = '\0'; cp = malloc( strlen(buf)+1 ); if ( cp == NULL ){ fprintf(stderr,"no memory\n"); exit(1); } strcpy(cp, buf); return cp; } int main() { char *arglist[MAXARGS + 1]; int numargs; char argbuf[ARGLEN]; numargs = 0; while (numargs < MAXARGS) { printf("Arg[%d]? ", numargs); if (fgets(argbuf, ARGLEN, stdin) && *argbuf != '\n') arglist[numargs++] = makestring(argbuf); else { if (numargs > 0) { arglist[numargs] = NULL; mybash20155310(arglist); numargs = 0; } } } return 0; }
截圖:
無
無
無
無
代碼行數(新增/累積) | 博客量(新增/累積) | 學習時間(新增/累積) | 重要成長 | |
---|---|---|---|---|
目標 | 2000行 | 30篇 | 400小時 | |
第一週 | 15 /100 | 1/2 | 1/20 | |
第二週 | 15/200 | 2/4 | 2/38 | |
第三週 | 15/300 | 3/7 | 3/60 | |
第四周 | 25/400 | 4/9 | 4/90 | |
第五週 | 25 /100 | 5/2 | 5/20 |
嘗試一下記錄「計劃學習時間」和「實際學習時間」,到期末看看能不能改進本身的計劃能力。這個工做學習中很重要,也頗有用。
耗時估計的公式
:Y=X+X/N ,Y=X-X/N,訓練次數多了,X、Y就接近了。
計劃學習時間:4小時
實際學習時間:1小時
改進狀況:
(有空多看看現代軟件工程 課件
軟件工程師能力自我評價表)