第二篇:認識ISA(Instruction Set Architecture)
重要概念:
- 【ISA】
- 【IA-32】:Intel把32位x86架構的名稱x86-32改稱為IA-32,一種身邊很常見的ISA
- 【內存模型】
- 【過程調用】
•ISA(Instruction Set Architecture)位於軟件和硬件之間
•硬件的功能通過ISA提供出來
•軟件通過ISA規定的"指令"使用硬件
•ISA規定了:
–可執行的指令的集合,包括指令格式、操作種類以及每種操作對應的操作數的相應規定;
–指令可以接受的操作數的類型;
–操作數所能存放的寄存器組的結構,包括每個寄存器的名稱、編號、長度和用途;
–操作數所能存放的存儲空間的大小和編址方式;
–操作數在存儲空間存放時按照大端還是小端方式存放;
–指令獲取操作數的方式,即尋址方式;
–指令執行過程的控制方式,包括程序計數器、條件碼定義等。
IA-32 規定的幾個方面:
『IA-32是CISC 復雜指令集』
- IA-32支持的數據結構類型和格式
- IA-32的寄存器組織
- IA-32的標志寄存器
- IA-32的尋址方式
- 浮點寄存器棧和多媒體擴展寄存器組
- IA-32 常用指令類型
》 程序的轉換與機器級表示
了解高級語言與匯編語言、
匯編語言與機器語言之間的關系
掌握有關指令格式、
操作數類型、
尋址方式、
操作類型等內容
了解高級語言源程序中的語句與機器級代碼之間的對應關系
了解復雜數據類型(數組、結構等)的機器級實現
0. IA-32寄存器模型
》 理解計算機是如何工作的
程序由指令組成
程序在執行前:
數據和指令事先存放在存儲器中,每條指令和每個數據都有地址,指令按序存放,指令由OP、ADDR字段組成,程序起始地址置PC
(原材料和菜譜都放在廚房外的架子上, 每個架子有編號。媽媽從第5個架上指定菜譜開始做)
開始執行程序:
第一步:根據PC取指令(從5號架上取菜譜)
第二步:指令譯碼(看菜譜)
第三步:取操作數(從架上或盤中取原材料)
第四步:指令執行(洗、切、炒等具體操作)
第五步:回寫結果(裝盤或直接送桌)
第六步:修改PC的值(算出下一菜譜所在架子號6=5+1)
繼續執行下一條指令(繼續做下一道菜)
》☆ 內存模型
作者注:
『不同語言有不同的內存模型。只有掌握了內存模型,才算是真正具有了對程序的時間和空間效率進行分析的基本能力。
如編譯性語言C、C++,對它們的分析要結合編譯出的匯編語言,同時也要注意操作系統和編譯器對內存管理的影響。
至於操作系統和編譯器對內存模型產生了何種影響,還需要進一步學習。』
Process virtual address space.
【圖片摘自 CSAPP 3rd】
. Heap.The code and data areas are followed immediately by the run-time heap. Unlike the code and data areas, which are fixed in size once the process begins running, the heap expands and contracts dynamically at run time as a result of calls to C standard library routines such as malloc and free.
堆,用於存放程序動態創建的數據。
. Shared libraries.Near the middle of the address space is an area that holds the code and data for shared libraries such as the C standard library and the math library. The notion of a shared library is a powerful but somewhat difficult concept.
共享存儲區:
靜態存儲區:存放共享數據
. Stack. At the top of the user's virtual address space is the user stack that the compiler uses to implement function calls. Like the heap, the user stack expands and contracts dynamically during the execution of the program. In particular, each time we call a function, the stack grows. Each time we return from a function, it contracts.
棧:用於程序調用過程中的數據存儲,局部變量。
. Kernel virtual memory. The kernel is the part of the operating system that is always resident in memory. The top region of the address space is reserved for the kernel. Application programs are not allowed to read or write the contents of this area or to directly call functions defined in the kernel code.
核心虛擬存儲區:操作系統專用存儲區。
》過程調用的機器級表示:
每次遞歸調用都會增加一個棧幀,所以空間開銷很大。
》IA-32的寄存器使用約定
調用者保存寄存器:EAX、EDX、ECX
當過程P調用過程Q時,Q可以直接使用這三個寄存器,不用將它們的值保存到棧中。如果P在從Q返回后還要用這三個寄存器的話,P應在轉到Q之前先保存,並在從Q返回后先恢復它們的值再使用。
被調用者保存寄存器:EBX、ESI、EDI
Q必須先將它們的值保存到棧中再使用它們,並在返回P之前恢復它們的值。
EBP和ESP分別是幀指針寄存器和棧指針寄存器,分別用來指向當前棧幀的底部和頂部。
》過程調用中兩種傳遞參數的方式:
1. 按值傳遞
2. 按地址傳遞
》數組的分配和訪問:
1. 分配到靜態區
全局變量、靜態數據
2. 分配在棧中,通過EBP來定位
局部變量、入口參數
》棧楨:
push %ebp
mov %esp,%ebp
每次跳轉都會執行兩跳語句構成棧底(在高地址)。ebp存放的是原ebp值
》 有時間可以去學習一下程序如何對應機器指令,即編譯成匯編語言的過程。
》 數據的訪問:
其中2、4沒有訪存操作,明白指針在提高執行效率時的厲害之處了吧。
》 數據的對齊
機器字長為固定的32位或64位。數據按字節編址,每一次訪問可能會跨越地址。
對齊的目的是:減少訪存次數,提高時間和空間效率。(畢竟數據總線每次讀好多個字節呢!)
> 數據的對齊
x86-64中各類型數據遵循一定的對齊規則,而且更嚴格
x86-64中存儲器訪問接口被設計成按8字節或16字節為單位進行存取,其對齊規則是,任何K字節寬的基本數據類型和指針類型數據的起始地址一定是K的倍數
例如int類型占用4個字節,地址只能在0,4,8等位置上。
> 對齊方式:
#pragma pack(n)
•為編譯器指定結構體或類內部的成員變量的對齊方式。
•當自然邊界(如int型按4字節、short型按2字節、float按4字節)比n大時,按n字節對齊。
•缺省或#pragma pack() ,按自然邊界對齊。
__attribute__((aligned(m)))
•為編譯器指定一個結構體或類或聯合體或一個單獨的變量(對象)的對齊方式。
•按m字節對齊(m必須是2的冪次方),且其占用空間大小也是m的整數倍,以保證在申請連續存儲空間時各元素也按m字節對齊。
__attribute__((packed))
l不按邊界對齊,稱為緊湊方式。
不同操作系統對齊策略可能有所不同。導致不同的結構聲明順序的內存利用效率不同。
Windosws策略:
Linux策略:
{
待補充~~
}
Ps:學習完這些就可以為后邊的緩沖區溢出做好准備了。
我來總結一下:
從以上內容可以看出來,人們做了大量工作去減少訪存次數,提高系統的時間和空間效率。因為相比訪問寄存器,訪問存儲器的開銷還是很大的。
注意在軟件方面同樣可以采取很多有效的措施減少訪存次數。
各種各樣的尋址方式也都是為了適應高級語言中的數據類型產生的訪存需要。
轉載請注明出處:http://www.cnblogs.com/learn-to-rock/p/5876337.html