汇编语言手册_第1页
汇编语言手册_第2页
汇编语言手册_第3页
汇编语言手册_第4页
汇编语言手册_第5页
已阅读5页,还剩18页未读 继续免费阅读

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

寄存器与存储器

1.寄存器功能

,寄存器的一般用途和专用月途

.CS:L控制程序执行流程

.SSS提供堆栈栈顶单元地址

.DS:BX(SI,DL提供数据段内单元地址

.SS:B.提供堆栈内单元地址

.ES:BX(SI,DL提供附加段内单元地址

.AX,CX,BX和CX寄存器多用于运算和暂存中间计算结果,但又专用于某些指令(查.

指令表)。

.PSW程序状态字寄存器只能通过专用指令(LAHF.SAHF)和堆栈(PUSHRPOPF)进行

存取。

2.存储器分段管理

.解决了16位寄存器构成20位地址的问题

.便于程序重定位

.20位物理地址二段地..1..偏移地址

.程序分段组织.一般由代码段,堆栈段,数据段和附加段组成,不设立堆栈段.则使用系

统内部的堆栈。

3.堆栈

.堆栈是一种先进后出的数据结..数据的存取在栈顶进.•数据入栈使堆栈向地址减小的

方向扩展。

.堆栈常用于保存子程序调月和中断响应时的断点以及暂存数据或中间计算结

.堆栈总是以字为单位存取

指令系统与寻址方式

1.指令系统

.计算机提供应用户使用的机器指令集称为指令系统,大多数指令为双操作数指令。执

行指令后,一般源操作数不变,目的操作数被计算结果替代。

.机器指令由CPU执行,完毕某种运算或操作,8086/8088指令系统中的指令分为6类.

数据传送,算术运算,逻辑运算,串操作,控制转移和解决机控制。

2.寻址方式

.寻址方式拟定执行指令时获得操作数地址的方法

.分为与数据有关的寻址方式(7种)和与转移地址有关的寻址方式(4)种。

.与数据有关的寻址方式的一般用途:

(1)立即数寻址方式-将常量赋给寄存器或存储单元

(2)直接寻址方式--存取单个变量

(3)寄存器寻址方式-访问寄存器的速度快于访问存储单元的速度

(4)寄存器间接寻址方式-访问数组元素

(5)变址寻址方式

(6)基址变址寻址方式

(7)相对基址变址寻址方式(5),(6),(7)都便于解决数组元素

.与数据有关的寻址方式中,提供地址的寄存器只能是BX,SI,DI或BP

.与转移地址有关的寻址方式的一般用途:

(1)段内直接寻址-段内直接转移或子程序调用

(2)段内间接寻址■■段内间接转移或子程序调用

(3)段间直接寻址-段间直接转移或子程序调用

(4)段间间接寻址-段间间接转移或子程序调用

汇编程序和汇编语言

1.汇编程序.汇编程序是将汇编语言源程序翻译成二进制代码程序的语言解决程序,翻

译的过程称为汇编。

2.汇编语言

.汇编语言是用指令助记符各种标记变量,地址,过程等的标记符书写程序的语言.汇编

语言指令与机器指令.一相应。.伪指令,宏指令不是由CPU执行的指令,而是由汇编程

序在汇编期间解决的指令。.伪指令指示汇编程序如何完毕数据定义,存储空间分派,

组织段等工作。.宏指令可简化程序并减少程序书写量。.条件汇编伪指令的功能是拟

定是否汇编某段源程序,而不是实现程序分支,对未汇编的程序将不产生相应的目的

代码。.结构作为一种数据结构可将一组类型不同但有逻辑关联的数据组织在一起,便.

整体解决数据。.记录可用于提高存储单元的运用率,将若干局限性一个字节或字且有

逻辑关联的•息压缩存放在一个字节或字中。.指令中的表达式在汇编期间计算,并且只

能对常量或地址进行计算。

程序设计基础

1.分支程序设计

.程序分支由条件转移指令或无条件转移指令实现.存放若干目的转移地址或跳转指

令的跳转表常用于实现多路分支.条件转移指令只能实现偏移量为-128至+127字节范

围的转移.无条件转移指令根据寻址方式可实现短转移(偏移量为-128至+127字节),段

内.移,段间转移。

2.循环程序设计.可由循环控制指令或条件转移指令组织循环结构,内层循环结构必须

完全包含在外层循环结构内,并不能发生从循环结构外向循.结构内的转移。

3.子程序设计.子程序中应保护寄存器内容,并对的使用堆栈.成对执行PUSH和POP

指令,保证执行RET指令时堆栈栈顶为返回地址。.主程序可通过寄存器,参数表,或堆

栈传递参数给子程.

4.EXE文献和COM文献

.两者都是可执行文献.COM文献源程序的特点是.第一条可执行指令的起始存放地址

必须是100H,不能分段,不用定义堆栈,所有过程为NEAR类型,直接用IN.20.指令返回

DOSo

5.DOS功能调用与BIOS中断调用

.两者都是完毕DOS系统提供应用户的输入/输出等常用功能,通过执行软中断指.完毕

一次软中断服务。.DOS功能调用的中断服务程序是操作系统的一部分,存于RAM中.

而BIOS中断调用的中断服务程序存放在ROM中。

输入/输出与中断系统

1.输入/输出的方式.程序直接I/O方式.用IN和OUT指令直接在端口级上进行I/O操

作,数据传送方.分为无条件传送方式和查询传送方式。.中断传送方式.由CPU响应中

断请求完毕中断服务。.DMA传送方式.直接在存储器与外设之间传送数据。

2.有关中断的概念

.中断、中断源、中断请求、中断服务、中断向量、中断向量表、中断响应过程、中

断指令、开中断、关中断、内部中断、外部中断、可屏蔽中断、非屏蔽口断。

3.键盘I/O、显示器I/O操作

.键盘的输入操作用BIOS的16H中断调用控制,也可直接访问60H端口(数据端

口).61H端口(状态端口)检测键盘的按键操作。.对于特殊键(如

Shif..Ctr..AL.NumLoc..ScrollLock等键)的按动情况,可以直接历来40:17H单元取得

有关信息。

.显示器的图形显示可以用BIOS的10H中断调用实现,另一种速度更快的方法是.接读

写视频缓冲区。4.打印机I/。操作.IN.l7H中断调用实现.串行通讯口操作.IN.l4H中断

调用实现。

CLDClearthedirectionflag(settoforwarddirection)将方向标志置0,使si和di增量,

串解决从低地址向高地址解决

8088汇编速查手册

一、数据传输指令它们在存贮器和寄存器、寄存器和输入输出端口之间传送数据.

1.通用数据传送指令.

MOV传送字或字节.

MOVSX先符号扩展,再传送.

MOVZX先零扩展,再传送.

PUSH把字压入堆栈.

POP把字弹出堆栈.

PUSHA把AX,CX.DX,BX.SP,BRSI,DI依次压入堆栈.

POPA把DI,SI,BP,SP,BX,DX,CX,AX依次弹出堆栈.

PUSHAD把EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI依次压入堆栈.

POPAD把EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX依次弹出堆栈.

BSWAP互换32位寄存器里字节的顺序

XCHG互换字或字节.(至少有一个操作数为寄存器,段寄存器不可作为操作数)

CMPXCHG比较并互换操作数.(第二个操作数必须为累加器AL/AX/EAX)

XADD先互换再累加.(结果在第一个操作数里)

XLAT字节查表转换.

一R指向一.25.字节的表的起点.A.为表的索弓.(0-255,即0-FFH).返A为查表结

果..[BX+AL卜〉A.)

2.输入输出端口传送指令.

INI/O端口输入..语法.1.累加器.{端标语|DX.)

OUTI/O端口输出..语法.OU.{端标语|DX},累加.)

输入输出端口由立即方式指定期,其范围是0-255;由寄存器DX指定期,其范围是

0-65535.

3.目的地址传送指令.

LEA装入有效地址.例.LE.DX,string;把偏移地址存到DX.

LDS传送目的指针,把指针内容装入DS.

例:LDSSI,string;把段地址:偏移地址存到DS:SI.

LES传送目的指针,把指针内容装入ES.

例:LESDI,string;把段地址:偏移地址存到ES:DI.

LFS传送目的指针,把指针内容装入FS.

例:LFSDI,string;把段地址:偏移地址存到FS:DL

LGS传送目的指针,把指针内容装入GS.

例:LGSDI,string;把段地址:偏移地址存到GS:DL

LSS传送目的指针,把指针内容装入SS.

例:LSSDI,string;把段地址:偏移地址存到SS:DI.

4.标志传送指令.

LAHF标志寄存器传送把标志装入AH.

SAHF标志寄存器传送,把AH内容装入标志寄存器.

PUSHF标志入栈.

POPF标志出栈.

PUSHD32位标志入栈.

POPD32位标志出栈.

二、算术运算指令

ADD力口法.

ADC带进位加法.

INC力口1.

AAA加法的ASCII码调整.

DAA加法的十进制调整.

SUB减法.

SBB带借位减法.

DEC减1.

NEC求凤以0减之).

CMP比较.(两操作数作减法,仅修改标志位,不回送结果).

AAS减法的ASCII码调整.

DAS减法的十进制调整.

MUL无符号乘法.

IMUL整数乘法.

以上两条,结果回送AH和AL(字节运算).或DX和AX(字运算),

AAM乘法的ASCII码调整.

DIV无符号除法.

IDIV整数除法.

以上两条,结果回送:

商回送AL,余数回送AH,(字节运算);

或商回送AX,余数回送DX,(字运算).

AAD除法的ASCII码调整.

CBW字节转换为字.(把AL中字节的符号扩展到AH中去)

CWD字转换为双字.(把AX中的字的符号扩展到DX中去)

CWDE字转换为双字.(把AX中的字符号扩展到EAX中去)

CDQ双字扩展.(把EAX中的字的符号扩展到EDX中去)

三、逻辑运算指令

AND与运算.

OR或运算.

XOR异或运算.

NOT取反

TEST测试.(两操作数作与运算,仅修改标志位,不回送结果).

SHL逻辑左移.

SAL算术左移.(=SHL)

SHR逻辑右移.

SAR算术右移.(二SHR)

ROL循环左移.

ROR循环右移.

RCL通过进位的循环左移.

RCR通过进位的循环右移.

以上八种移位指令,其移位次数可达255次.

移位一次时,可直接用操作码.如SHLAXJ.

移位>1次时,则由寄存器CL给出移位次数.

如MOVCL,04

SHLAX,CL

四、串指令

DS:SI源串段寄存器:源串变址.

ES:DI目的串段寄存器:目的串变址.

CX反复次数计数器.

AL/AX扫描值.

D标志0表达反复操作中SI和DI应自动增量;1表达应自动减量.

Z标志用来控制扫描或比较操作的结束.

MOVS串传送.

.MOVSB传送字符.MOVSW传送字.MOVSD传送双字.)

CMPS串比较.

.CMPSB比较字符,CMPSW比较字)

SCAS串扫描.

把AL或AX的内容与目的串作比较,比较结果反映在标志位.

LODS装入串.

把源串中的元素(字或字节)逐个装入AL或AX中.

.LODSB传送字符.LODSW传送字.LODSD传送双字.)

STOS保存串.是LODS的逆过程.

REP当CX/ECXoO时反复.

REPE/REPZ当ZF=1或比较结果相等,且CX/ECX<>0时反复.

REPNE/REPNZ当ZF=0或比较结果不相等,且CX/ECX<>0时反复.

REPC当CF=1且CX/ECX<>0时反复.

REPNC当CF=0且CX/ECXoO时反复.

五、程序转移指令

1>无条件转移指令(长转移)

JMP无条件转移指令

CALL过程调用

RET/RETF过程返回.

2>条件转移指令(短转移「128到+127的距离内)

(当且仅当(SFXOROF)=1时,OP1<OP2)

JA/JNBE不小于或不等于时转移.

JAE/JNB大于或等于转移.

JB/JNAE小于转移.

JBE/JNA小于或等于转移.

以上四条,测试无符号整数运算的结果(标志C和Z).

JG/JNLE大于转移.

JGE/JNL大于或等于转移.

JL/JNGE小于转移.

JLE/JNG小于或等于转移.

以上四条,测试芍符号整数运算的结果(标志S,0和Z).

JE/JZ等于转移.

JNE/JNZ不等于时转移.

JC有进位时转移.

JNC无进位时转移.

JNO不溢出时转移.

JNP/JPO奇偶性为奇数时转移.

JNS符号位为“0”时转移.

JO溢出转移.

JP/JPE奇偶性为偶数时转移.

JS符号位为“1”时转移.

3>循环控制指令(短转移)

LOOPCX不为零时循环.

LOOPE/LOOPZCX不为零且标志Z=l时循环.

LOOPNE/LOOPNZCX不为零且标志Z=()时循环.

JCXZCX为零时转移.

JECXZECX为零时转移.

4>中断指令

INT中断指令

INTO溢出中断

IRET中断返回

5>解决器控制指令

HLT解决器暂停,直到出现中断或复位信号才继续.

WAIT当芯片引线TEST为高电平时使CPU进入等待状态.

ESC转换到外解决器.

LOCK封锁总线.

NOP空操作.

STC置进位标志位.

CLC清进位标志位.

CMC进位标志取反.

STD置方向标志位.

CLD清方向标志位.

STI置中断允许位.

CLI清中断允许位.

六、伪指令

DW定义字(2字节).

PROC定义过程.

ENDP过程结束.

SEGMENT定义段.

ASSUME建立段寄存器寻址.

ENDS段结束...END程序结束.

汇编语言基础知识

汇编语言和CPU以及内存,端口等硬件知识是连在一起的.这也是为什么汇编语言没

有通用性的因素.下面简朴讲讲基本知识(针对INTE.x86及其兼容机)

x86汇编语言的指令,其操作对象是CPU上的寄存器,系统内存,或者立即数.有些

指令表面上没有操作数.或者看上去缺少操作数.其实该指令有内定的操作对象,比

如push指令.一定是对SS:ESP指定的内存操作.而cdq的操作对象一定是ea..edx.

在汇编语言中,寄存器用名字来访问.CP.寄存器有好几类.分别有不同的用处:

L通用寄存器:

EAX,EBX,ECX,EDX,ESI,EDI,EBP,ESP(这个虽然通用,但很少被用做除了堆栈指

针外的用途)

这些32位可以被用作多种用途,但每一个都有〃专长〃.EA,是〃累加器〃(accumula

tor).它是很多加法乘法指令的缺省寄存器.EB.是"基地址〃(base)寄存器.在内存寻

址时存放基地址.EC.是计数器(counter).是反复(REP)前缀指令和LOOP指令的内定

计数器.EDX是...(忘了..哈哈)但它总是被用来放整数除法产生的余数.这4个寄存

器的低16位可以被单独访问,分别用AX,BX,CX和DX.AX又可以单独访问低8位(AL)

和高8位(AH).BX,CX,DX也类似.函数的返回值经常被放在EAX中.

ESI/EDI分别叫做〃源/目的索引寄存器〃(source/destinatio.index),由于在很

多字符串操作指令中.DS:ESI指向源串,而ES:EDI指向目的字

EBP是〃基址指针〃(BAS.POINTER).它最经常被用作高级语言函数调用的〃框架指

针〃(fram.pointer).在破解的时候,经常可以看见一个标准的函数起始代码:

pus.eb.;保存当前ebp

mo.ebp,es.;EBP设为当前堆栈指针

su.esp.xx.;预留xxx字节给函数临时变量.

•••

这样一来,EB.构成了该函数的一个框架.在EBP上方分别是本来的EBP.返回地址

和参数.EBP下方则是临时变量.函数返回时.mo.esp,ebp/po.ebp/re.即可.

ES.专门用作堆栈指针.

2.段寄存器:

CS(Cod.Segment,代码段.指定当前执行的代码段.EI.(Instructio.pointer.

指令指针)则指向该段中一个具体的指令.CS:EIP指向哪个指令.CP.就执行它.一般

只能用jmp.ret.jnz.cal.等指令来改变程序流程,而不能直接对它们赋值.

DS(DAT.SEGMENT.数据段.指定一个数据段.注意:在当前的计算机系统中.代码

和数据没有本质差别.都是一串二进制数.区别只在于你如何用它.例如.C.制定的段

总是被用作代码.一般不能通过CS指定的地址去修改该段.然而,你可认为同一个段

申请一个数据段描述符〃别名〃而通过DS来访问/修改.自修改代码的程序常如此做.

ES,FS,G.是辅助的段寄存器.指定附加的数据段.

SS(STAC.SEGMENT)指定当前堆栈段.ES.则指出该段中当前的堆栈顶.所有push/

po.系列指令都只对SS:ESP指出的地址进行操作.

3.标志寄存器存FLAGS):

该寄存器有32位,组合了各个系统标志.EFLAGS一般不作为整体访问.而只对单

一的标志位感爱好.常用的标志有:

.进位标志C(CARRY).在加法产生进位或减法有借位时置1.否则为0.

零标志Z(ZERO).若运算结果为0则置1.否则为0

符号位S(SIGN),若运算结果的最高位置1.则该位也置1.

溢出标志O(OVERFLOW).若(带符号)运算结果超过可表达范围.则置1.

JX.系列指令就是根据这些标志来决定是否要跳转.从而实现条件分枝.要注意,

很多JX.指令是等价的.相应相同的机器码.例如.J.和J,是同样的,都是当Z=1是跳

转.只有JM.是无条件跳转.JX.指令分为两组.分别用于无符号操作和带符号操作.JX.

后面的〃XX.有如下字母:

无符号操作.带符号操作:

../zABOVE".表达〃高于..."GREATER”.表达〃大于〃

一〃BELO旷.表达〃低于...〃LESS〃,表达〃小于〃

…〃CARRY”.表达〃进位〃或〃借位.…〃OVERFLOW”.表达〃溢出〃

・.〃SIGN〃,表达〃负〃

通用符号:

一〃EQUAL.表达〃等于〃.等价于.(ZERO)

..〃NOT.表达〃非〃.即标志没有置位.如JN.〃假如Z没有置位则跳转〃

一〃ZERO".与E同.

假如仔细想一想,就会发・J..JNBE.JA..JNB.JB..JNA.J..JNLE.JGE.JNL.JL.JNG

E....

4.端口

端口是直接和外部设备通讯的地方。外设接入系统后,系统就会把外设的数据

接口映射到特定的端口地址空间,这样,从该端口读入数据就是从外设读入数据,

而向外设写入数据就是向端口写入数据。当然这一切都必须遵循外设的工作方式。

端口的地址空间与内存地址空间无关,系统总共提供对64K个8位端口的访问,编

号0-65535.相邻的8位端口可以组成成一个16位端口,相邻的16位端口可以组成

一个32位端口。端口输入输出由指令IN,OUT,INS和OUTS实现,具体可参考汇编语

言书籍。

汇编指令的操作数可以是内存中的数据,如何让程序从内存中对的取得所需

要的数据就是对内存的寻址。

INTEL的CPU可以工作在两种寻址模式:实模式和保护模式。前者已通过时,

就不讲了,WINDOWS现在是32位保护模式的系统,PE文献就基本是运营在一个

32位线性地址空间,所以这里就只介绍32位线性空间的寻址方式。

其实线性地址的概念是很直观的,就想象一系列字节排成一长队,第一个字

节编号为0,第二个编号位1,oooo一直到(十六进制FFFFFFFF,这是32位

二进制数所能表达的最大值了)。这已有4GB的容量!足够容纳一个程序所有的代

码和数据。当然,这并不表达你的机器有那么多内存。物理内存的管理和分派是

很复杂的内容,初学者不必在意,总之,从程序自身的角度看,就好象是在那

么大的内存中。

在INTEL系统中,内存地址总是由〃段选择符:有效地址〃的方式给出。段选择

符(SELECTOR)存放在某一个段寄存器中,有效地址则可由不同的方式给出。段选

择符通过检索段描述符拟定段的起始地址,长度(又称段限制),粒度,存取权

限,访问性质等。先不用深究这些,只要知道段选择符可以拟定段的性质就行

了。一旦由选择符拟定了段,有效地址相对于段的基地址开始算。比如由选择符

1A7选择的数据段,其基地址是400000,把1A7装入DS中,就拟定使用该数据

段。DS:O就指向线性地址400000。DS:1F5278就指向线性地址5E5278。我们在

一般情况下,看不到也不需要看到段的起始地址,只需要关心在该段中的有效地

址就行了。在32位系统中,有效地址也是由32位数字表达,就是说,只要有

一个段就足以涵盖4GB线性地址空间,为什么还要有不同的段选择符呢?正如前面

所说的,这是为了对数据进行不同性质的访问。非法的访问将产生异常中断,而

这正是保护模式的核心内容,是构造优先级和多任务系统的基础。这里有涉及到

很多深层的东西,初学者先可不必理睬。

有效地址的计算方式是:基址+间址*比例因子+偏移量。这些量都是指段内的

相对于段起始地址的量度,和段的起始地址没有关系。比如,基址=100000,间

址二400,比例因子二4,偏移量二20230,则有效地址为:

100000+400*4+20230=100000+1000+20230=121000。相应的线性地珏是400000

+121000=521000。(注意,都是十六进制数)。

基址可以放在任何32位通用寄存器中,间址也可以放在除ESP外的任何一个

通用寄存器中。比例因子可以是1,2,4或8。偏移量是立即数。如:[EBP+E

DX*8+200]就是一个有效的有效地址表达式。当然,多数情况下用不着这么复杂,

间址,比例因子和偏移量不一定要出现。

内存的基本单位是字节(BYTE)o每个字节是8个二进制位,所以每个字节能

表达的最大的数是11111111,即十进制的255。一般来说,用十六进制比较方便,

由于每4个二进制位刚好等于1个十六进制位,11111111b=OxFFo内存中的

字节是连续存放的,两个字节构成一个字(WORD),两个字构成一个双字(DWORD)o

在INTEL架构中,采用smallendian格式,即在内存中,高位字节在低位字节

后面。举例说明:十六进制数803E7D0C,每两位是一个字节,在内存中的形式是:

0C7D3E80o在32位寄存器中则是正常形式,如在EAX就是803E7D0C。当我们

的形式地址指向这个数的时候,事实上是指向第一个字节,即0C。我们可以指定访

问长度是字节,字或者双字。假设DS:[EDX]指向第一个字节0C:

movAL,byteptrDS:[EDX];把字节0C存入AL

movAX,wordptrDS:[EDX];把字7D0C存入AX

movEAX,dwordptrDS:[EDX];把双字803E7D0C存入EAX

在段的属性中,有一个就是缺省访问宽度。假如缺省访问宽度为双字(在32位

系统中经常如此),那么要进行字节或字的访问,就必须用byte/wordptr显式地指

明。

缺省段选择:假如指令中只有作为段内偏移的有效地址,而没有指明在哪一个

段里的时候,有如下规则:

假如用ebp和esp作为基址或间址,则认为是在SS拟定的段中;

其他情况,都认为是在DS拟定的段中。

假如想打破这个规则,就必须使用段超越前缀。举例如下:

moveax,dwordptr[edx];缺省使用DS,把DS:[EDX]指向的双字送入eax

movebx,dwordptrES:[EDX];使用ES:段超越前缀,把ES:[EDX]指向的双

字送入ebx

堆栈:

堆栈是一种数据结构,严格地应当叫做“栈”。“堆”是另一种类似但不同的

结构。SS和ESP是INTEL对栈这种数据结构的硬件支持。push/pop指令是专门针

对栈结构的特定操作。SS指定一个段为栈段,ESP则指出当前的栈顶。pushxxx指

令作如下操作:

把ESP的值减去4;

把xxx存入SS:[ESP]指向的内存单元。

这样,esp的值减小了4,并且SS:[ESP]指向新压入的xxx。所以栈是“倒着

长”的,从高地址向低地址方向扩展。popyyy指令做相反的操作,把SS:[ESP]指

向的双字送到yyy指定的寄存器或内存单元,然后把esp的值加上4。这时,认为该

值已被冲出,不再在栈上了,由于它虽然还暂时存在在本来的栈顶位置,但下一个

pus上操作就会把它覆盖。因此,在栈段中地址低于esp的内存单元中的数据均被认

为是未定义的。

最后,有一个要注意的事实是,汇编语言是面向机器的,指令和机器码基本上

是一一相应的,所以它们的实现取决于硬件。有些看似合理的指令事实上是不存在

的,比如:

movDS:[edx],ds:[ecx];内存单元之间不能直接传送

movDS,1A7;段寄存器不能直接由立即数赋值

movEIP,3D4E7;不能对指令指针直接操作。

高级语言程序的汇编解.

在高级语言中,如C和PASCAL等等,我们不再直接对硬件资源进行操作,而是

面向于问题的解决,这重要体现在数据抽象化和程序的结构化。例如我们用变量名

来存取数据,而不再关心这个数据究竟在内存的什么地方。这样,对硬件资源的使

用方式完全交给了编译器去解决。但是,一些基本的规则还是存在的,并且大多数

编译器都遵循一些规范,这使得我们在阅读反汇编代码的时候日子好过一点。这里

重要讲讲汇编代码中一些和高级语言相应的地方.

1.普通变量。通常声明的变量是存放在内存中的。编译器把变量名和一个内存

地址联系起来(这里要注意的是,所谓的“拟定的地址”是对编译器而言在编译阶

段算出的一个临时的地址。在连接成可执行文献并加载到内存中执行的时候要进行

重定位等一系列调整,才生成一个实时的内存地址,但是这并不影响程序的逻辑,

所以先不必太在意这些细节,只要知道所有的函数名字和变量名字都相应一个内存

的地址就行了),所以变量名在汇编代码中就表现为一个有效地址,就是放在方括

号中的操作数。例如,在C文献中声明.

in.my_age.这个整型的变量就存在一个特定的内存位置。语.my_age.32.在反汇

编代码中也许表现为.

mo.wor.pt.[007E85DA].2.

所以在方括号中的有效地址相应的是变量名。又如.

cha.my_name[ll..,zlianzi2023z,.

这样的说明也拟定了一个地址,相应于my_name.假设地址是007E85DC,则内存

中[007E85DC]=T,[007E85DD]=i*.etc.对my_name的访问也就是对这地址处的数

据访问.

指针变量其自身也同样相应一个地址,由于它自身也是一个变量。如.

cha.*your_name.这时也拟定变量〃yourname”相应一个内存地址,假设为007E

85F0.语句yourname=myname;很也许表现为.

mo.[007E85F0].007E85D.;yourname的内容是myname的地址.

2.寄存器变.

在C和C++中允许说明寄存器变量。registe.in.i.指明i是寄存器存放的整型

变量。通常,编译器都把寄存器变量放在esi和edi中。寄存器是在cpu内部的结

构,对它的访问要比内存快得多,所以把频繁使用的变量放在寄存器中可以提高程

序执行速度.

3.数.

不管是多少维的数组,在内存中总是把所有的元素都连续存放,所以在内存中

总是一维的。例如,in.i_array[2][3],在内存拟定了一个地址,从该地址开始的1

2个字节用来存贮该数组的元素。所以变量名i_array相应着该数组的起始地址,

也即是指向数组的第一个元素。存放的顺序一般是i_array[0][0],[0][1],[0][2],

[1][0],口][1],[1][2.即最右边的下标变化最快。当需要访问某个元素时,程序就

会从多维索引值换算成一维索引,如访问换算成内存中的一维索引

值就是1*3+1=4.这种换算乜许在编译的时候就可以拟定,也也许要到运菅时才可以

拟定。无论如何,假如我们把[array相应的地址装入一个通用寄存器作为基址,

则对数组元素的访问就是一个计算有效地址的问题.

.i_array[1][l]=0xl.

Ie.ebx,xxxxxxx.;i_arra.相应的地址装入eb.

mo.edx,0.;访问i_array[1][1],编译时就己经拟.

mo.wor.pt.[ebx+edx*2].1..

当然,取决于不同的编译器和程序上下文,具体实现也许不同,但这种基本的

形式是拟定的。从这里也可以看到比例因子的作用(还记得比例因子的取值为1,2,

4或8吗?),由于在目前的系统中简朴变量总是占据1,2,4或者8个字节的长度,

所以比例因子的存在为在内存中的查表操作提供了极大方便.

4.结构和对.

结构和对象的成员在内存中也都连续存放,但有时为了在字边界或双字边界对

齐,也许有些微调整,所以要拟定对象的大小应当用sizeof操作符而不应当把成员

的大小相加来计算。当我们声明一个结构变量或初始化一个对象时,这个结构变量

和对象的名字也相应一个内存地址。举例说明.

struc.tag_info_struc..

in.age.

in.sex.

floa.height.

.floa.weight.

,marry.

变量marry就相应一个内存地址。在这个地址开始,有足够多的字节(sizeof(m

arn))容纳所有的成员。每一个成员则相应一个相对于这个地址的偏移量。这里假

设此结构中所有的成员都连续存放,则age的相对地址为0,sex为2.heigh.为4,w

eight为8.

.marry.sex=0.

Ie.ebx,xxxxxxx.;marr.相应的内存地.

mo.wor.pt.[ebx+2]..

对象的情况基本相同。注意成员函数具体的实现在代码段中,在对象中存放的

7E个指向该函数的指针.

5.函数调.

一个函数在被定义时,也拟定一个内存地址相应于函数名字。如.

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论