- 幾個常用寄存器: https://www.cnblogs.com/xiangtingshen/p/11089586.html
- 匯編轉移指令jmp原理: https://blog.csdn.net/lanuage/article/details/52904704
- 第一章: CPU與寄存器: https://www.mallocfree.com/basic/asm/asm-0-register.htm
- 寄存器介紹: https://blog.csdn.net/lidonghat/article/details/70244288
- 匯編中cmov指令: http://blog.chinaunix.net/uid-28458801-id-3558590.html
- 匯編指令: https://www.jianshu.com/p/77d8c406b034
- 匯編中的PTR含義 https://blog.csdn.net/fireblue1990/article/details/52530248
- 反匯編 https://cs61.seas.harvard.edu/site/2018/Asm1/
- 匯編入門: https://blog.csdn.net/lwwl12/article/details/102994403
- 深入理解計算機系統(3.8)---數組、異質結構以及指針的詳解 https://www.cnblogs.com/zuoxiaolong/p/computer20.html
- 深入理解計算機系統 -- 程序的機器級表示 https://www.cnblogs.com/lawliet12/p/11852003.html
幾個常用寄存器: https://www.cnblogs.com/xiangtingshen/p/11089586.html
sp/esp/rsp(16bit/32bit/64bit)棧寄存器---指向棧頂
bp/ebp/rbp 棧基址寄存器---指向棧底
ip/eip/rip 程序指令寄存器---指向下一條待執行指令
數據寄存器組:
EAX, EBX, ECX, EDX,ABCD都是32位數據寄存器,E表示 externed 拓展
匯編轉移指令jmp原理: https://blog.csdn.net/lanuage/article/details/52904704
在計算機中存儲的都是二進制數,計算機將內存中的某些數當做代碼,某些數當做數據。在根本上,將cs,ip寄存器所指向的內存當做代碼,指令轉移就是修改cs,ip寄存器的指向,匯編中提供了一種修改它們的指令——jmp。
jmp指令可以修改IP或cs和IP的值來實現指令轉移,指令格式為:”jmp 標號“將指令轉移到標號處,例如:
CODES SEGMENT
ASSUME CS:CODES
START:
MOV AX,0
jmp s
第一章: CPU與寄存器: https://www.mallocfree.com/basic/asm/asm-0-register.htm
好的程序員,應該是懂匯編語言的程序員。匯編語言在程序調試中是不可回避的。分析匯編語言在某些時候是必須的,而有的程序就沒有源代碼和符號表,那么唯一可以利用的就是它的反匯編語言了。在一些底層開發中,還需要在代碼中嵌入匯編語言。Linux內核也是通過C與匯編寫出來的。因此,首先介紹一下匯編語言的基礎。
1.1寄存器
CPU的一個重要組成部分就是它的寄存器。計算機體系結構中常用到的寄存器包括以下幾類寄存器:
1.1.1 32位寄存器
32位寄存器是以e開頭的,主要包含下面一些寄存器:
a) 通用寄存器:EAX,EBX,ECX,EDX
b) 源變址目標變址寄存器:ESI,EDI
c) 棧相關積存器:SS,ESP(棧頂指針寄存器),EBP(棧基址寄存器)
d) 代碼段寄存器,程序指令寄存器:CS,EIP(指令寄存器)
e) 數據段寄存器:DS(常與ESI寄存器結合使用)
f) 附加段寄存器:ES(常與EDI寄存器集合使用)
g) 控制寄存器:CR0-CR3。
寄存器介紹: https://blog.csdn.net/lidonghat/article/details/70244288
寄存器是CPU的組成部分,因為在CPU內,所以CPU對其讀寫速度是最快的,不需要IO傳輸,
但同時也決定了此類寄存器數量非常有限,有限到幾乎每個存儲都有自己的名字,而且有些還有多個名字。
IA-32構架提供了16個基本寄存器,這16個基本寄存器可以歸納為如下幾類:
通用寄存器
段寄存器
狀態和控制寄存器
指令寄存器
通用寄存器
32位通用寄存器有八個,eax, ebx, ecx, edx, esi, edi, ebp, esp,
他們主要用作邏輯運算、地址計算和內存指針,具體功能如下:
eax 累加和結果寄存器 https://blog.csdn.net/xiazdong/article/details/7388945
ebx 數據指針寄存器
ecx 循環計數器
edx i/o指針
esi 源地址寄存器
edi 目的地址寄存器
esp 堆棧指針
ebp 棧指針寄存器
匯編中cmov指令: http://blog.chinaunix.net/uid-28458801-id-3558590.html
匯編指令: https://www.jianshu.com/p/77d8c406b034
寄存器與內存:
CPU的指令是不支持內存挪內存的,如果要挪動必須通過寄存器;
CPU做運算需要通過寄存器中轉,計算結束后存入內存 ;比如:對3加1操作,就不能直接在內存中對3加1,然后再開辟空間存儲4
通常,CPU會先將內存中的數據存儲到寄存器中,然后再對寄存器中的數據進行運算
假設內存中有一個紅色內存空間的值是3,現在想把它的值加1,並將結果存儲到藍色內存空間
- CPU首先會將紅色內存空間的值放到rax寄存器中:
movq 紅色內存空間, %rax
- 然后讓rax寄存器與1相加:
addq $0x1, %rax
- 最后將得到的值,賦值給藍色內存空間:
movq %rax, 藍色內存空間
常見匯編指令:
常見寄存器
有16個常用寄存器
rax 、rbx、rcx、rdx、rsx、rdi、rbp、rsp
r8、r9、r10、r11、r12、r13、r14、r15
寄存器的具體用途
rax、rdx常作為函數返回值使用
rdi、rsi、rdx、rcx、r8、r9等寄存器常用於存放函數參數
rsp、rdp用於棧操作
rip 作為指令指針 存儲着CPU下一條要執行的指令的地址,一旦CPU讀取一條指令,rip會自動指向下一條指令(存儲下一條指令的地址)
r開頭:64bit, 8字節
e開頭:32bit, 4字節
ax,bx,cx: 16bit, 2字節
ah, al: 8bit, 1字節
規律:
內存地址格式為: 0x4bdc(%rip), 一般是全局變量,全局區(數據段)
內存地址格式為:-0x78(%rbp), 一般是局部變量,棧空間
內存地址格式為:0x10(%rax), 一般是堆空間
movq 指令每次只能夠移動8個字節
callq *%rax 間接訪問寄存器中的地址給它發消息
匯編中的PTR含義 https://blog.csdn.net/fireblue1990/article/details/52530248
ptr -- pointer (即指針)的縮寫。匯編里面 ptr 是規定的字(即保留字),是用來臨時指定類型的。(可以理解為,ptr是臨時的類型轉換,相當於C語言中的強制類型轉換)
mov ax,bx ;是把bx寄存器里的值賦予ax,由於二者都是word型,所以沒有必要加“WORD”。
mov ax,word ptr [bx] ;是把內存地址等於“bx寄存器的值”的地方所存放的數據,賦予ax。由於只是給出一個內存地址,不知道希望賦予ax的是byte還是word,所以需要用word明確指出!
所以,當兩個操作數的寬度不一樣時,就要用到ptr。
總結:
不管用在什么位置,ptr的作用就是臨時指定類型。可以放在ptr前面的類型有byte(字節)、word(字)、dword(雙字)、qword(四字)、tbyte(十字節)、far(遠類型)和near(近類型)
反匯編 https://cs61.seas.harvard.edu/site/2018/Asm1/
Registers
Instruction format
Directives
Address modes
Address computations
%rip-relative addressing
匯編入門: https://blog.csdn.net/lwwl12/article/details/102994403
1.1 常用寄存器
1.2 常用指令
1.3 其他
深入理解計算機系統(3.8)---數組、異質結構以及指針的詳解 https://www.cnblogs.com/zuoxiaolong/p/computer20.html
從上面的匯編分析來看,我們可以很輕松的得到一個結論,那就是數組變量其實就是數組的起始地址,就像動態數組例子當中的%esi寄存器一樣,它代表着數組a變量,同時也是數組的起始地址。而對於指針的運算,在計算實際地址時,會根據數據類型進行伸縮,比如動態數組一例中,每次在取數組元素時,總有一個權重值是4(比如這個在上面出現過的內存地址(%esi,%edx,4),它就是在讀取數組元素),這正是int類型的長度。
深入理解計算機系統 -- 程序的機器級表示 https://www.cnblogs.com/lawliet12/p/11852003.html
假設有源文件 p1.c 和 p2.c,使用 gcc -Og -o p p1.c p2.c 編譯生成代碼,-Og 會告訴編譯器使用符合原始 C 代碼整體結構的機器代碼優化等級。(PS: -O0 所得到的匯編代碼實用價值極小,幾乎沒有什么用處,建議使用 -Og 或者 -O1(有的較早的編譯器可能不認識 -Og,這是 GCC 4.8 之后引入的內容),可讀性會更高)。