- 几个常用寄存器: 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
- 汇编入门: 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 累加和结果寄存器
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 间接访问寄存器中的地址给它发消息
汇编入门: 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 之后引入的内容),可读性会更高)。