Linux(10.5-10.11)学习笔记
3.2程序编码
unix> gcc -01 -o p p1.c p2.c
-o用于指定输出(out)文件名。
-01,-02 告诉编译器使用第一级或第二级优化
3.2.1机器级代码
机器级编程两种重要的抽象:
1.ISA(指令集体系结构):机器级程序的格式和行为,叙述成按顺序执行,一条指令结束后,下一条再开始。
2.机器级程序使用的储存器地址是虚拟地址,提供的储存器模型看上去是一个非常大的字节数组。
IA32:
1.程序计数器
2.整数寄存器文件
3.条件码寄存器保存着最近执行的算术或逻辑指令的状态信息。
4.一组浮点寄存器存放浮点数据。
3.2.2代码示例

gcc -S -o code.s code.c产生一个汇编文件code.svim code.s

objdump -d xxx.xx使用反汇编器查看目标代码文件的内容。

机器代码和它的反汇编表示的一些特性:
1.IA32指令长度从1到15个字节不等
2.设计指令格式的方式是,从某个给定位置开始,可以将字节唯一的解码成机器指令
3.反汇编器只是基于机器代码文件中的字节序列来确定汇编代码,不需要访问程序的源代码或汇编代码
4.反汇编器使用的指令命名规则与GCC生成的汇编代码使用的有些差别
3.3数据格式
8 位:字节
16位:字
32位:双字
64位:四字
16位的机器体系结构,Intel用术语"字(word)"表示16位数据类型。
32位机器体系结构是从16位扩展过来,因此称32位数为“双字(double words)”,称64位数为“四字(quad words)”。
大部分指令都是针对字节和双字操作的。
C声明 Intel数据类型 GAS后缀 大小(字节)
char 字节(byte) b 1
short 字(word) w 2
int 双字(double words) l 4
unsigned 双字(double words) l 4
long int 双字(double words) l 4
unsigned long 双字(double words) l 4
char * 双字(double words) l 4
float 单精度(signal) s 4
double 双精度(double) l 8
long double 扩展精度 t 10/12
GAS中的每个操作指令都有一个字符后缀,用于表明操作数的大小。例如,mov有三种形式: movb(传送字节)、movw(传送字)、movl(传送双字)。其中float的后缀也是l,这不会与整数的混淆,因为浮点数使用的一组完全不同的指令和寄存器(浮点数寄存器)。
3.4访问信息
在IA32中央处理单元(CPU)中,包含了8个32位整数寄存器。在每个32位寄存器的名字前面都会有一个%e,在这里可以把e理解成extended(扩展的),因为早期的8086寄存器是16位,所以加e之后就变成32位的了。

3.4.1操作数指示符
操作数指示符包括立即数,寄存器,存储器。
|
类型 |
格式 |
操作数值 |
名称 |
|
立即数 |
$Imm |
Imm |
立即数寻址 |
|
寄存器 |
Ea |
R[Ea] |
寄存器寻址 |
|
存储器 |
Imm |
M[Imm] |
绝对寻址 |
|
存储器 |
(Ea) |
M[R[Ea]] |
间接寻址 |
|
存储器 |
Imm(Eb) |
M[Imm + R[Eb]] |
(基址+偏移量)寻址 |
|
存储器 |
(Eb, Ei) |
M[R[Eb] + R[Ei]] |
变址寻址 |
|
存储器 |
Imm(Eb, Ei) |
M[Imm + R[Eb] + R[Ei]] |
变址寻址 |
|
存储器 |
(, Ei, s) |
M[R[Ei] * s] |
比例变址寻址 |
|
存储器 |
Imm(, Ei, s) |
M[Imm + R[Ei] * s] |
比例变址寻址 |
|
存储器 |
(Eb, Ei, s) |
M[R[Eb] + R[Ei]*s] |
比例变址寻址 |
|
寄存器 |
Imm (Eb, Ei, s) |
M[Imm + R[Eb] + R[Ei]*s] |
比例变址寻址 |
3.4.2数据传送指令
将数据从一个位置复制到另一个位置的指令是最频繁使用的指令

传送指令MOV
MOV reg/mem,imm ;立即数送寄存器或是存储器
MOV reg/mem/seg,reg ;寄存器送寄存器(包括段寄存器)或贮存
MOV reg/seg,mem ;主存送寄存器(包括段寄存器)
MOV reg/mem,seg ;段寄存器送主存或寄存器
特别说明:(1)立即数传送至通用寄存器(不包括段寄存器)或存储单元
(2)IA32的限制:两个操作数都不能指向存储器。
3.5算术和逻辑操作
3.5.1加载有效地址 3.5.2一元和二元操作 3.5.3移位操作
加载有效地址指令leal 实际上是movl指令的变形,它的指令形式是从储存器读数据到寄存器,但实际上它没用引用储存器。

一元操作
只有一个操作数,既是源又是目的,可以是一个寄存器,或者存储器位置。
二元操作
操作数既是源又是目的
·第一个操作数可以是立即数、寄存器或者存储器位置 第二个操作数可以是寄存器或者存储器位置 但是不能同时是存储器位置。
移位操作
SAL 算术左移
SHL 逻辑左移
SAR 算术右移(补符号位)
SHR 逻辑右移(补0)
3.5.5特殊的算术操作
imull
双操作数,从两个32位操作数产生一个32位的乘积。
mull
无符号数乘法
要求一个参数必须在寄存器%eax中,另一个作为指令的源操作数给出。乘积的高32位在%edx中,低32位在%eax中。
idivl
有符号除法
操作数
将DX:AX中的64位数作为被除数,操作数中为除数,结果商在AX中,余数在DX中。
divl无符号除法
通常会事先设定寄存器%edx为0.
3.6控制
3.6.1条件码
条件语句、循环语句和分支语句,要求有条件的进行,根据数据测试的结果来决定操作执行的顺序。机器代码提供两种基本的低级机制来实现有条件的行为:测试数据值,然后根据测试的结果来改变控制流或者数据流
控制指令-条件码
CPU维护着一组单个位的条件码寄存器,他们描述了最近的算术或者逻辑操作的属性。可以检测这些寄存器来执行条件分支指令
最常用的条件码:
CF:进位标志。最近的操作使最高位产生了进位。可以用来检查无符号操作数的溢出
ZF:零标志。最近的操作得出的结果为0.
SF:符号标志。最经的操作得到的结果为负数。
OF:溢出标志。最近的操作导致一个补码溢出——正溢出或者负溢出
比较和测试指令
有两类指令只设置条件码而不改变任何其他寄存器。
CMP指令根据两个操作数之间的差来设置条件码。
TEST指令的行为同and一样。典型的用法是,testl %eax,%eax用来检查%eax是负数、零还是正数
3.6.2访问条件码
三种方法
1.根据条件码的某个组合,将一个字节设置为0或者1
2.可以条件跳转到程序的某个其他的部分
3.可以有条件地传送数据
3.6.3、跳转指令及其编码
jump分为直接跳转和间接跳转
直接跳转:后面跟标号作为跳转目标
间接跳转:*后面跟一个操作数指示符
3.6.4翻译条件分支
将条件表达式和语句从c语言翻译成机器语言,最常用的方式就是结合有条件和无条件跳转。
无条件跳转:例如 goto。书上的例子就是把if-else语句翻译成了goto形式,然后再由这个形式翻译成汇编语言。
3.6.5循环
1.Do-while循环
源代码
do{
body-statement
}while(test-expr)
翻译成汇编的伪代码
loop:
body-statement;
t = test-expr;
if(t)
goto loop;
2.While循环
源代码
while(test-expr)
body-statement
翻译成汇编的伪代码
t = test-expr;
if(!t)
goto done;
loop:
body-statement;
t = test-expr;
if(t)
goto loop;
done:
For循环
源代码:
for(init-expr;
test-expr;
update-expr)
body-statement;
翻译成汇编的伪代码:
init-expr;
t = test-expr;
if(!t)
goto done;
loop:
body-statement;
update-expr;
t = test-expr;
if(t)
goto loop;
done:
switch语句
根据一个整数索引值进行多重分支,执行switch语句的关键步骤是通过跳转表来访问代码位置,使结构更加高效。
3.7过程
数据传递、局部变量的分配和释放通过操纵程序栈来实现。
3.7.1栈帧结构
· 为单个过程分配的栈叫做栈帧,寄存器%ebp为帧指针,而寄存器指针%esp为栈指针,程序执行时栈指针移动,大多数信息的访问都是相对于帧指针。
· 栈向低地址方向增长,而栈指针%esp指向栈顶元素。
3.7.2转移控制
call:目标是指明被调用过程起始的指令地址,效果是将返回地址入栈,并跳转到被调用过程的起始处。
ret:从栈中弹出地址,并跳转到这个位置。
函数返回值存在%eax中
3.7.3寄存器使用惯例
程序寄存器是唯一能被所有过程共享的资源,调用者保存寄存器 和 被调用者保存寄存器是分开的,对于哪一个寄存器保存函数调用过程中的返回值要有统一的约定。
3.11使用GDB调试器

|
命令 |
参数含义 |
说明 |
|
display |
设置自动显示列表,不带参数时显示列表中所有表达式 |
|
|
delete display dnums….. |
自动显示列表的ID号 |
删除自动显示列表 |
|
disable dislay dnums….. |
自动显示列表的ID号 |
禁用自动显示列表 |
|
enable display dnums….. |
自动显示列表的ID号 |
使用自动显示列表 |
|
info display |
显示自动显示列表中的表达式 |
|
|
show convenience |
显示快捷变量 |
|
|
macro expand expression |
包含宏定义的表达式 |
将表达式宏展示 |
|
info macro macroname |
宏定义的名字 |
查看宏定义的信息 |
|
generatre-core file |
产生转储文件 |
|
|
backtrace |
n 最内层的n个函数栈帧 -n 最外层n个函数栈帧 |
栈帧回溯 |
|
frame |
栈帧号或者内存地址 |
选定栈帧,不带参数时显示栈帧简要信息 |
|
up |
栈帧号 |
选定栈帧上移 |
|
down |
栈帧号 |
选定栈帧下移 |
|
info frame |
显示栈帧详细信息 |
|
|
info agrs |
显示当前选定栈帧的函数参数 |
|
|
info locals |
显示当前选定栈帧中的所有局部变量 |
|
|
set variable expr |
赋值表达式 |
给变量赋值或者修改变量的值 |
|
|
赋值表达式 |
给变量赋值或者修改变量的值 |
|
jump |
使程序从另外的地址开始执行 |
|
|
signal sig |
信号值或者信号和名称 |
向被调试程序发送信号 |
|
call expr |
包含函数调用的表达式 |
调用函数 |
|
print expr |
包含函数调用的表达式 |
调用函数 |
|
list |
函数名 行号 地址 偏移等 |
列出程序源码 |
|
set listsize count |
设置 list默认显示的行数 |
|
|
disassemble |
反汇编被调试程序 |
|
|
set disassembly-flavor instruction-set |
设置反汇编格式 |
|
命令 |
参数含义 |
说明 |
|
display |
设置自动显示列表,不带参数时显示列表中所有表达式 |
|
|
delete display dnums….. |
自动显示列表的ID号 |
删除自动显示列表 |
|
disable dislay dnums….. |
自动显示列表的ID号 |
禁用自动显示列表 |
|
enable display dnums….. |
自动显示列表的ID号 |
使用自动显示列表 |
|
info display |
显示自动显示列表中的表达式 |
|
|
show convenience |
显示快捷变量 |
|
|
macro expand expression |
包含宏定义的表达式 |
将表达式宏展示 |
|
info macro macroname |
宏定义的名字 |
查看宏定义的信息 |
|
generatre-core file |
产生转储文件 |
|
|
backtrace |
n 最内层的n个函数栈帧 -n 最外层n个函数栈帧 |
栈帧回溯 |
|
frame |
栈帧号或者内存地址 |
选定栈帧,不带参数时显示栈帧简要信息 |
|
up |
栈帧号 |
选定栈帧上移 |
|
down |
栈帧号 |
选定栈帧下移 |
|
info frame |
显示栈帧详细信息 |
|
|
info agrs |
显示当前选定栈帧的函数参数 |
|
|
info locals |
显示当前选定栈帧中的所有局部变量 |
|
|
set variable expr |
赋值表达式 |
给变量赋值或者修改变量的值 |
|
|
赋值表达式 |
给变量赋值或者修改变量的值 |
|
jump |
使程序从另外的地址开始执行 |
|
|
signal sig |
信号值或者信号和名称 |
向被调试程序发送信号 |
|
call expr |
包含函数调用的表达式 |
调用函数 |
|
print expr |
包含函数调用的表达式 |
调用函数 |
|
list |
函数名 行号 地址 偏移等 |
列出程序源码 |
|
set listsize count |
设置 list默认显示的行数 |
|
|
disassemble |
反汇编被调试程序 |
|
|
set disassembly-flavor instruction-set |
设置反汇编格式 |
实验楼实验五
要求
使用gcc –S –o main.s main.c -m32
命令编译成汇编代码,如下代码中的数字和函数名请自行修改以防与他人雷同
int g(int x){return x + 3;}int f(int x){return g(x);}int main(void){return f(8) + 1;}
1.删除gcc产生代码中以"."开头的编译器指令,针对每条指令画出相应栈帧的情况
2.(选做)使用gdb的bt/frame/up/down 指令动态查看调用栈帧的情况
实验结果




2.


参考资料:
http://blog.csdn.net/21cnbao/article/details/7385161
http://blog.csdn.net/nabila/article/details/7786428
Linux(10.5-10.11)学习笔记的更多相关文章
- linux内核分析第四周学习笔记
linux内核分析第四周学习笔记 标签(空格分隔): 20135328陈都 陈都 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.co ...
- C++11 学习笔记 std::function和bind绑定器
C++11 学习笔记 std::function和bind绑定器 一.std::function C++中的可调用对象虽然具有比较统一操作形式(除了类成员指针之外,都是后面加括号进行调用),但定义方法 ...
- Linux内核分析第二周学习笔记
linux内核分析第二周学习笔记 标签(空格分隔): 20135328陈都 陈都 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.co ...
- linux内核分析第一周学习笔记
linux内核分析第一周学习笔记 标签(空格分隔): 20135328陈都 陈都 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.co ...
- Linux就该这么学11学习笔记
参考链接:https://i.cnblogs.com/EditPosts.aspx?opt=1 文件传输协议 一般来讲,人们将计算机联网的首要目的就是获取资料,而文件传输是一种非常重要的获取资料的方式 ...
- zepto源码--核心方法10(位置)--学习笔记
今天基本上就是zepto学习笔记的最后一篇了,介绍一下有关位置的函数,position, offset, scrollLeft, scrollTop scrollLeft 如果所选取的包装集不存在,则 ...
- Linux简易APR内存池学习笔记(带源码和实例)
先给个内存池的实现代码,里面带有个应用小例子和画的流程图,方便了解运行原理,代码 GCC 编译可用.可以自己上网下APR源码,参考代码下载链接: http://pan.baidu.com/s/1hq6 ...
- C++11学习笔记
C++11 1.long long新类型 2.列表初始化 int t=0; int t={0}; int t(0); int t{0}; 注意:如果我们使用列表初始化有丢失信息的风险,则编译器报错 l ...
- linux下文件搜索命令学习笔记
1. locate:按照文件名搜索文件 locate filename 与find在整个操作系统中遍历搜索不同,locate命令在/var/lib/mlocate这个后台数据库中按照文件名搜索,所以优 ...
- Linux文件与目录管理(学习笔记)
本笔记为<鸟哥linux私房菜>第六章学习笔记 一.目录与路径 相对路径与绝对路径 绝对路径:一定由根目录 / 写起 正确度比较好 相对路径:不是由 / 写起 ...
随机推荐
- 深入理解CSS中的层叠上下文和层叠顺序
零.世间的道理都是想通的 在这个世界上,凡事都有个先后顺序,凡物都有个论资排辈.比方说食堂排队打饭,对吧,讲求先到先得,总不可能一拥而上.再比如说话语权,老婆的话永远是对的,领导的话永远是对的. 在C ...
- Atitit.一个cms有多少少扩展点,多少api wordpress cms有多少api。。扩展点
Atitit.一个cms有多少少扩展点,多少api wordpress cms有多少api..扩展点 1. Api分类 WordPress APIs1 1.1. 1 函数分类2 1.2. 函数api ...
- SoapUI接口测试实例(webservice接口)
接口测试步骤 注:以测试queryHistoryAccepts接口作举例. 1. 用户登录获取SessionKey实体信息 注:由于大部分的接口都需要SessionKey实体的信息,因此测试那些接口都 ...
- JavaScript Patterns 4.2 Callback Pattern
function writeCode(callback) { // do something... callback(); // ... } function introduceBugs() { // ...
- C# 图片处理(压缩、剪裁,转换,优化)
1.图片与二进制的转换 图片转换成二进制主要用于数据库存储及图片数据的应用间传输,如网站服务器通过WebService或WCF从数据处理服务器获取图片数据,就可以以二进制形式传输 ///图片转二进制 ...
- Python开发之【简单计算器】
开发一个简单的python计算器 1.实现加减乘除及括号优先级解析 2.用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * ...
- Hive query issue
One time, I have written a query with two tables join, One table is big table with partitions , anot ...
- java读取word内容
暂时只写读取word内容的方法. 依赖的jar: poi-3.9-20121203.jarpoi-ooxml-3.9-20121203.jarxmlbeans-2.3.0.jar package co ...
- selenium如何操作cookies实现免登录
执行接口测试或者某些自动化测试时,为了避免每次访问接口都需要登录操作,可以用访问接口时,把cookies信息传过去. 思路是先登录一次页面,获取到cookies信息,把cookies信息保存到本地文件 ...
- 【温故而知新-Javascript】图片效果(图像震动效果、闪烁效果、自动切换图像)
1.当鼠标指针经过图像时图像震动效果 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " ...