汇编语言学习笔记一

一 数据表示
1
十进制结尾用D或d
二进制结尾用B或b
十六进制结尾用H或h
八进制结尾用Q或q

2 字符的ASCII表示
标准的ASCII字符集分为4组,每组32个字符。
第一组 0~1FH 是一组不可打印字符,称为控制字符
第二组 各种标点符号、专用字符和数字
第三组 26个大写字母(41H~5AH)及6个专用字符
第四组 26个小写字母及(61H~7AH)5个专用字符和一个控制符

3 BCD
BCD是一种十进制数的二进制编码表示,有以下两种格式:
a 压缩BCD格式
 用4个二进制位表示一个十进制位
b 非压缩BCD格式

4 CPU
cpu主要由算术逻辑部件、控制部件和寄存器组成,其任务是执行内存中的指令序列。


5 汇编程序通常以.s作为文件名后缀
as hello.s -o hello.o
ld hello.o -o hello

6 汇编程序中以.开头的 名称并不是指令的助记符,不会被翻译成机器指令。
.section指示把代码划分成若干个段,程序被操作系统加载执行时,每个段被加载到不同的地址,具有不同的读、写、执行权限。
.data断保存程序的数据,是可读可写的,C程序的全局变量属于.data段

符号在汇编中代表一个地址,可以用在指令中。

movl $1,%eax//数据传送指令,CPU内部产生一个数字1,然后传送到eax寄存器中。mov的后缀l表示long,说明是32位的传送指令。

CPU内部产生的数叫做立即数,在汇编程序中,立即数前面要加$,寄存器前面要加%,以便跟符号名区分开。

int $0x80
a int指令称为软中断指令,可以用这条指令故意产生一个异常,异常的处理和中断类似,CPU从用户模式切换到特权模式,然后跳转到内核代码中执行异常处理程序。
b int指令中哦姑娘的立即数0x80是一个参数,在异常处理中要根据这个参数决定如何处理。在linux内核中int 0x80这种异常称为系统调用。
c eax和ebx寄存器的值是传递给系统调用的两个参数。eax的值是系统调用号,1表示_exit调用,ebx的值则是传递给_exit的参数,也就是退出状态。

7 X86的寄存器
X86的通用寄存器有eax、ebx、ecx、edx、edi、esi。
除法指令要求被除数在eax寄存器中,余数在edx寄存器中。

X86的特殊寄存器有ebp、esp、eip、efiags。
eip:程序计数器
eflags:保存计算过程中产生的标志位
进位 CF 溢出 OF 零ZF 负数 SF

ebp和esp用于维护函数调用的堆栈。

data_items:
 .long 3,67,34,222,45,75,54,34,44,33,22,11,66,0
.long指示声明一组数,每个数占32位,相当于C中的数组
数组开头有个标号data_items,汇编器会把数组的首地址作为data_items符号所代表的地址。

出了.long之外,常用的数据声明还有:
.byte 声明一组数,每个数占8位
.ascii 例如:.ascii "hello word"

edi(目的变址寄存器)寄存器保存数组的当前位置。
ebx 保存到目前为止找到的最大值。

movl data_items(,%edi,4), %eax
把数组的第0个元素传送到eax寄存器上。data_items是数组的首地址,edi的值是数组的下标,4表示数组的每个元素占有4个字节。那么数组第edi个元素的地址应该是data_items+edi*4。

start_loop表示开始循环,loop_exit表示结束循环。

cmpl $0, %eax
cmpl指令将两个操作数相减,但计算结果并不保存,只是根据计算结果改变eflags寄存器中的标志位。如果两个操作数相等,则计算结果为0,eflags中的ZF位置1。
je是一个条件跳转指令,它检查eflags中的ZF位,ZF位为1则发生跳转,ZF位为0则不跳转。
比较指令和条件跳转指令是配合使用的,前者改变标志位,后者根据标志位作出判断。

incl %edi  //将edi 的值加1

cmpl %ebx, %eax
jle start_loop
把当前数组元素eax和目前为止找到的最大值ebx 做比较,如果前者小于等于后者,则最大值没有变,跳转到循环开头比较下一个数,否则继续执行下一条指令。jle 也是一个条件跳转指令,le表示less than or equal。

jmp 是一个无条件跳转指令,什么条件也不判断,直接跳转。

8 寄存器
1 eax 累加器   2 ebx 基址寄存器  3 ecx 计数寄存器  4 edx 数据寄存器

1~~4 数据寄存器

5 esi 源变址寄存器  6 edi 目的变址寄存器

5~6变地寄存器
1~~6 通用寄存器

7 ebp 基址指针 8 esp 堆栈指针

7~8 指针寄存器
 
9 eflags 标志寄存器 10 eip 指令指针

9~~10 专用寄存器

11 CS 代码寄存器 12 ds 数据断寄存器 13 ss 堆栈寄存器 14 es 附加段寄存器

11~~14 段寄存器

15 fs

16 gs

9 寻址方式
内存寻址在指令中可以表示成如下的通用格式:
ADDRESS_OR_OFFSET(%BASE_OR_OFFSET,%INDEX,MULTIPLIER)
它所表示的地址可以这样计算出来:
FINAL ADDRESS = ADDRESS_OR_OFFSET + BASE_OR_OFFSET + MULTIPLIER * INDEX

其中ADDRESS_OR_OFFSET和MULTIPLIER必须是常数,BASE_OR_OFFSET和INDEX必须是寄存器

直接寻址:
只使用ADDRESS_OR_OFFSET寻址,例如movl ADDRESS, %eax 把ADDRESS地址处的32位数传送到eax 寄存器。

变址寻址(Indexed Addressing Mode) 。movl data_items(,%edi,4), %eax 就属于这种寻址方式,用于访问数组元素比较方便。

间接寻址(Indirect Addressing Mode)。只使用BASE_OR_OFFSET寻址,例如movl (%eax), %ebx ,把eax 寄存器的值看作地址,把这个地址处的32位数传送到ebx 寄存器。注意和movl %eax, %ebx 区分开。

基址寻址(Base Pointer Addressing Mode)。只使用ADDRESS_OR_OFFSET和BASE_OR_OFFSET寻址,例如movl 4(%eax), %ebx ,用于访问结构体成员比较方便,例如一个结构体的基地址保存在eax 寄存器中,其中一个成员在结构体内的偏移量是4字节,要把这个成员读上来就可以用这条指令。

立即数寻址(Immediate Mode)。就是指令中有一个操作数是立即数,例如movl $12,%eax 中的$12 ,这其实跟寻址没什么关系,但也算作一种寻址方式。

寄存器寻址(Register Addressing Mode)。就是指令中有一个操作数是寄存器,例如movl $12, %eax 中的%eax ,这跟内存寻址没什么关系,但也算作一种寻址方式。

10 ELF文件
可重定位的目标文件(Relocatable)
可执行文件(Executable)
共享库(Shared Object)

目标文件:
ELF文件格式提供了两种不同的视角,在汇编器和链接器看来,ELF文件是由Section Header Table描述的一系列Section的集合,而执行一个ELF文件时,在加载器(Loader)看来它是由Program Header Table描述的一系列Segment的集合。

我们在汇编程序中用.section 声明的Section会成为目标文件中的Section,此外汇编器还会自动添加一些Section(比如符号表)。

Segment是指在程序运行时加载到内存的具有相同属性的区域,由一个或多个Section组成,比如有两个Section都要求加载到内存后可读可写,就属于同一个Segment。

目标文件需要链接器做进一步处理,所以一定有Section Header Table;可执行文件需要加载运行,所以一定有Program Header Table;而共享库既要加载运行,又要在加载时做动态链接,所以既有Section Header Table又有Program Header Table。

  们知道,C语言的全局变量如果在代码中没有初始化,就会在程序加载时用0初始化。这种数据属于.bss 段,在加载时它和.data 段一样都是可读可写的数据,但是在ELF文件中.data 段需要占用一部分空间保存初始值,而.bss 段则不需要。也就是说,.bss 段在文件中只占一个Section Header而没有对应的Section,程序加载时.bss 段占多大内存空间在Section Header中描述。

.rel.text 告诉链接器指令中的哪些地方需要重定位

objdump工具可以把程序中的机器指令反汇编

转载于:https://www.cnblogs.com/wangtianxj/archive/2009/06/26/1511860.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值