汇编语言程序设计简明教程:第2章数据定义与传送_第1页
汇编语言程序设计简明教程:第2章数据定义与传送_第2页
汇编语言程序设计简明教程:第2章数据定义与传送_第3页
汇编语言程序设计简明教程:第2章数据定义与传送_第4页
汇编语言程序设计简明教程:第2章数据定义与传送_第5页
已阅读5页,还剩91页未读 继续免费阅读

下载本文档

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

文档简介

汇编语言程序设计

简明教程1第二章数据定义与传送

2.1数据的定义 2.2数据的传送 2.3汇编语言上机操作 习题二2

2.1 数据的定义

2.1.1数据段2.1.2数据定义3汇编语言程序定义的“数据”:(1)

变量(Varible)

有一个名字,运行过程中值可能发生变化,可以有

“初始值”。(2)

常数(Constant)

常数可以直接写在指令内,也可以存放在数据段内。(3)

缓冲区(Buffer)

从输入设备输入若干数据时,在数据段里事先留出必要

的存储单元,称为“输入缓冲区”。 输出一批数据时,把输出内容事先存放在若干内存单元

中,称为“输出缓冲区”。42.1.1数据段DATA SEGMENT;在这里定义数据;;……DATA ENDS

DATA: 程序员给这个段起的名字。

SEGMENT:保留字,说明一个段从这里开始。

ENDS: 保留字,说明一个段到此结束。

; 分号后面的文字是“注释”,不参加汇编5语句”:由一行文字构成, 是一条指令, 或者定义一组数据, 或者是一条“伪指令”。伪指令:说明性的语句62.1.2数据定义数据定义伪指令:[变量名]数据定义伪操作数据[,数据]……数据定义伪操作:

DB(DefineByte):每个数据占用一个字节(8b)DW(DefineWord):每个数据占用一个字(16b)DD(DefineDoubleWord):每个数据占用一个双字(32b)DQ(DefineQuartWord):每个数据占用8个字节(64b)DT(DefineTenByte):每个数据占用10个字节(80b)7DATA SEGMENTX db -1,255,‘A’,3+2,? db “ABC”,0FFH,11001010BY db 3dup(?)DATA ENDS数据定义举例(1):有符号数用它的补码存储字符用它的ASCII代码存储

db定义的数据在[-128~255]之内变量名代表这个单元的地址?表示一个尚未确定的值,用0先行填充

DUP表示重复定义8DSEG SEGMENTZ DW-2,-32768,65535,‘AB’W DD12345678H,-400000 DWZ,W-ZDSEG ENDS数据定义举例(2):

DW定义的数据在(-32768,+65535)内出现在数据部分的变量名代表这个变量的偏

移地址多字节数据的高位存放在较高地址单元中9变量X,Y,Z,W的属性变量名段属性SEG偏移地址OFFSET类型TYPE长度LENGTH大小SIZEXDATA0000H111YDATA000AH133ZDSEG0000H212WDSEG0008H212102.2数据的传送2.2.1 指令格式2.2.2 程序段2.2.3 基本传送指令2.2.4 其他传送指令2.2.5 堆栈2.2.6 操作数表达式11汇编语言程序由若干“语句”组成,每个“语句”占用一行。三种类型语句:指令语句:包含一条符号指令,与一条机器指令相对应,

汇编以后成为这条机器指令的二进制代码,这

个代码被称为“目标(Object)”;伪指令语句:一条说明性的语句。有的伪指令语句汇编后

没有“结果”,有的伪指令汇编后产生“目标”。注释行:书写说明性文字,不进行“汇编”,也不产生

“目标”。121.80X86指令格式[标号:]程序员给这一行起的名字,后面跟上冒号,代表这一行的地址。标号用字母开始,不要使用保留字作为标号。操作码是这条指令需要完成的操作,用指令助记符表示。[操作数]是指令的操作对象,指令的操作数可以有0~3个。两个操作数时,右面的操作数称为“源操作数”,左面的操作数称为“目的操作数”。[;注释]用来添加一些说明,例如说明本行指令的功能。[标号:]操作码[操作数][;注释]132.

操作数寄存器操作数:包括段寄存器,通用数据、地址寄存器。例如:

MOV BX,AX功能:AX寄存器内容送入BX寄存器。

AX是“源操作数”,写在右边,指令执行后,它的

内容不会被改变。

BX是“目的操作数”,写在左边,指令执行后,它的

内容将被改变。注意:寄存器IP/EIP和FLAGS/EFLAGS不能作为操作数出现

在指令中。14立即数操作数:二进制/十进制/十六进制常数,可求值的表

达式,字符,标号等都可以用作操作数。假设已经定义:X DW 150指令“MOV BX,X*2”是错误的,“变量”的计算应该在用户程序执行时进行,“汇编程序”不能对“变量”进行计算。常数300送入BX寄存器

MOV BX,300或者:MOV BX,150*2DATA段的段基址送DS MOV AX,DATA MOV DS,AX注意:立即数不能用作“目的操作数”。15为了对存储器的一个单元进行访问,需要给出这个单元的段基址和偏移地址。大多数情况下,指令使用DS寄存器的内容作为操作数的段基址,指令中不需要再指出段基址。3.存储器操作数指出偏移地址的方法有两种:直接的和间接的。常常在程序开始处把数据段的段基址装入DS寄存器:

MOV AX,DATA MOV DS,AX16直接(偏移)地址:在指令里直接写出存储单元的偏移地址。DATA SEGMENTA DB 12,34,56ARRAYDW55,66,77,88,99DATA ENDS假设已把DATA代表的段基址装入DS把变量(数组)A的前两个数据送BL,BH寄存器:

MOVBL,A ;也可以写作MOVBL,[A]MOVBH,A+1;或MOVBH,[A+1],MOVBH,A[1]A代表数据“12”的偏移地址,A+1是数据“34”的偏移地址。错误!MOVBX,A ;把变量[A]送BL,变量[A+1]送BH17直接(偏移)地址:在指令里直接写出存储单元的偏移地址。DATA SEGMENTA DB 12,34,56ARRAYDW55,66,77,88,99DATA ENDS假设已把DATA代表的段基址装入DS,并且知道A的偏移地址是0000H,前面的指令可以写作:

MOVBL,[0000H];方括号不能省略

MOVBH,[0001H];方括号不能省略常数地址格式一般没有实用价值。上面的两条指令可以用一条指令代替,效果相同:MOVBX,[0000H];取地址0000H开始的两字节,送入BL和BH18MOVAL,[2100H];正确,8位传送指令,2100H是字节地址MOVAX,[2100H];正确,16位传送指令,2100H是字地址MOVEAX,[2100H];正确,32位传送指令,2100H是双字地址假设已经定义:X DW 150

指令MOVBX,X 是16位传送指令,正确

指令MOVBL,X 是错误的,操作数类型不匹配19间接(偏移)地址:把存储单元的偏移地址先装入某个寄存器,通过这个寄存器来找到这个存储单元,称为“寄存器间接寻址”。已经定义:ADB12,34MOV SI,OFFSETA;把变量A的偏移地址装入SI ;OFFSET是保留字,表示取出后面变量的偏移地址MOV BL,[SI] ;变量A的第一个值送BLMOV BH,[SI+1] ;第二个值送BH,等同于MOVBH,1[SI] 16位80X86微处理器只有BX,BP,SI,DI这4个寄存器可以用来“间接寻址”。不另加说明的话,使用BP时自动用SS的值作为段基址,使用BX,SI,DI时自动用DS的值作为段基址。20已经定义:ARRAY DW35,73,27,780,12,55

取出字数组ARRAY的第3个元素送入AX:;方法1MOVAX,ARRAY[4];ARRAY代表数组首地址,位移量=4,直接寻址;也可以写作“MOVAX,ARRAY+4”;方法2MOVBX,OFFSETARRAY;数组首地址装入BXMOVAX,[BX+4];第3个元素距数组首元素4个字节;方法3MOVBX,4 ;第3个元素距数组首地址的位移量装入BXMOVAX,ARRAY[BX];ARRAY代表数组首地址,BX中是位移量21基址变址寻址:用两个寄存器联合起来寻址。从(BX,BP)和(SI,DI)中

各选出一个使用。出现BP时使用SS作为段基址寄存器,其它情况用DS。MOVAX,ARRAY[4] ;直接寻址,偏移地址=ARRAY+4MOVAX,[BX] ;寄存器间接寻址MOVAX,[BX+2] ;寄存器相对寻址 ;BX中存放首地址,位移量2MOVAX,ARRAY[BX];寄存器相对寻址 ;ARRAY为首地址,BX中存放位移量MOVAX,[BX+SI] ;基址(BX)变址(SI)寻址MOVAX,[BX+DI+2] ;相对基址变址寻址2232位80x86微处理器的存储器寻址: [基址+比例因子×变址+位移量]基址:任何一个32位通用寄存器,使用EBP时将SS的值作为

段基址,其它情况下使用DS的值作为段基址;变址:任何一个32位通用寄存器;比例因子:常数1,2,4,8;位移量:常数;2332位80x86微处理器的存储器寻址举例: MOVAX,ARRAY[4] ;直接寻址,有效地址=ARRAY+4MOVAX,[ECX] ;可以用任何一个通用寄存器间接寻址MOVAX,[EAX+4] ;寄存器相对寻址MOVAX,[EBX+ECX];基址(EBX)变址(ECX)寻址MOVAX,[EBP+EDX+4]

;相对基址(EBP)变址(EDX)寻址,使用SSMOVAX,[EBX+4*ESI]

;变址寄存器可以乘上比例因子1,2,4,8MOVAX,[8*EBP+ECX+6]

;相对基址(ECX)变址(EBP)寻址,使用DS24在“实地址模式”下,偏移地址用16位二进制表示,用于寻址的32位寄存器的高16位必须为0。MOVAX,[EBX][EBP];基址(EBX)变址(EBP)寻址,使用DSMOVAX,[EBP][EBX];基址(EBP)变址(EBX)寻址,使用SSMOVAX,[EBX][EBP*1]

;基址(EBX)变址(EBP)寻址,使用DSMOVAX,[1*EBP][EBX]

;基址(EBP)变址(EBX)寻址,使用SS第二条指令等同于:MOV AX,[EBP][EBX]。带有比例因子的寄存器一般作为变址寄存器,比例因子为1时:252.2.2程序段假设已定义数据段为“DATA”,程序段常见格式:CODE SEGMENTASSUME CS:CODE,DS:DATASTART: MOV AX,DATA MOV DS,AX ;其他指令

MOV AX,4C00H INT 21HCODE ENDS END START26“ASSUME”伪指令用来指定段和段寄存器之间的对应关系,供汇编程序使用。DATA SEGMENT A DB 55DATA ENDSDSEG SEGMENT X DB 10DSEG ENDSASSUMEDS:DATA,ES:DSEG MOV AX,DATA MOV DS,AX MOV AX,DSEG MOV ES,AX设变量A和X的偏移地址都是0000H。指令MOVAL,A自动按照MOVAL,DS:[0000H]的格式

汇编,执行后(AL)=55,结果正确。指令MOVDL,X自动按照MOVDL,ES:[0000H]的格式

汇编,执行后(DL)=10,结果正确。27MOVSI,OFFSETA;A的偏移地址装入SIMOVDI,OFFSETX;X的偏移地址装入DIMOVAL,[SI] ;取A的值送ALMOVDL,[DI] ;取X的值送DL执行的结果:(AL)=55

正确,(DL)=55

错误。为了得到正确结果,上面第4条指令改写为:MOV DL,ES:[DI] ;执行后(DL)=10,结果正确这条指令“显式”地指定了段基址,汇编出来的机器指令比MOVDL,[DI]多一个字节,称为“段跨越前缀”。28“START”是第一条指令的“标号”。标号出现在指令行前面,标号与指令之间用冒号“:”分开。本程序的执行从标有“START”的第一条指令开始,它的地址称为这个程序的“入口地址”。指令“INT21H”表示调用由操作系统提供的21H号服务程序。AH中为“功能号”,AH=4CH表示返回操作系统的操作。AL中的代码称为“返回代码”,00H表示“正常返回”。29处理器选择伪指令.386.386P.486.486P.586.586P.686.686P.386表示程序选用80386的基本指令集,

.386P表示选用80386的基本指令和保护模式下的特权指令。缺省的处理器选择伪指令是.8086302.2.3 基本传送指令MOV指令的一般格式:

1.MOV(Move,传送)指令MOV指令把源操作数(source)传送到目的操作数(destination)MOV dest,src设指令执行前,(AX)=2345H,(BX)=1111H。

指令“MOVAX,BX”执行后,(AX)=1111H,(BX)=1111H。

源操作数BX的内容被复制到AX寄存器内,源操作数BX的内容保持不变,目的操作数AX的原内容被覆盖。31源操作数可以是:寄存器、存储器、立即数;目的操作数可以是:寄存器、存储器。32MOV指令的使用限制:源操作数与目的操作数可以是字节、字或双字,但必须有

相同的类型;源操作数与目的操作数不能同时为存储器操作数;目的操作数不能是立即数;

FLAGS、EFLAGS、IP、EIP不能用作操作数。对于段寄存器作为操作数的MOV指令:源操作数与目的操作数不能同时为段寄存器;目的操作数是段寄存器时,源操作数只能是寄存器或存储

器,不能是立即数;

CS不能用作目的操作数。33MOV CL,DH ;字节传送指令,DH寄存器内容送入CLMOV ECX,EDX ;

双字传送指令,EDX寄存器内容送入ECXMOV AX,CS ;字传送指令,CS寄存器内容送入AXMOV SS,CX ;字传送指令,CX寄存器内容送入SSMOV指令举例(寄存器、寄存器操作数):正确:错误:MOV CL,DX ;操作数类型不匹配MOV ESI,BH ;操作数类型不匹配MOV CS,AX ;CS寄存器不能作为目的操作数MOV DS,CS ;不能同时为段寄存器34MOV AL,30H ;字节传送指令,执行后(AL)=30HMOV AX,30H ;字传送指令,执行后(AX)=0030HMOV EAX,30H ;

双字传送指令,执行后(EAX)=00000030HMOV AL,-5 ;字节传送指令,执行后(AL)=0FBHMOV AX,-5 ;字传送指令,执行后(AX)=0FFFBHMOV指令举例(立即数、寄存器操作数):正确:错误:MOV 30H,AL ;立即数不能用作目的操作数MOV AL,300 ;源操作数超出范围35MOV指令举例(存储器、寄存器操作数):正确:错误:MOV [BP],BL ;

字节传送指令,BL寄存器内容送SS:[BP]MOV [BX],AX ;字传送指令,AL内容送DS:[BX],

;AH内容送DS:[BX+1]MOV DX,[SI] ;字传送指令,DS:[SI]内容送入DL, ;DS:[SI+1]内容送入DH假设变量X_BYTE用DB定义,变量Y_WORD用DW定义MOV [DX],BL ;DX寄存器不能用来寄存器间接寻址MOVX_BYTE,AX ;操作数类型不匹配36MOV指令举例(存储器、立即数操作数):正确:错误:MOV X_BYTE,-5 ;字节传送指令,-5(0FBH)送X_BYTEMOV Y_WORD,-5 ;字传送指令,-5(0FFFBH)送Y_WORD假设变量X_BYTE用DB定义,变量Y_WORD用DW定义MOV X_BYTE,300 ;源操作数超出范围MOV [BX],30H ;

操作数类型不能确定37错误:MOV X_BYTE,[SI] ;不能同时为存储器操作数MOV X_BYTE,K_BYTE ;不能同时为存储器操作数MOV SS,DS ;不能同时为段寄存器操作数两个操作数不能同时为存储器操作数或段寄存器!38MOV BYTEPTR[BX],20H ;1B立即数20H送DS:[BX]MOV WORDPTR[BX],20H ;立即数20H送DS:[BX],

;00H送DS:[BX+1]MOV DWORDPTR[BX],20H ;4B立即数00000020H送

;DS:[BX]开始4个字节MOV BYTEPTR[Y_WORD],20H;立即数20H送变量

;Y_WORD的第一字节MOV AL,BYTEPTR[Y_WORD];变量Y_WORD的第一字节

;送AL寄存器MOV WORDPTR[X_BYTE],20H;2B立即数0020H送变量

;X_BYTE开始的2字节可以用“类型PTR”指定,或强行改变操作数的类型:39LEA把源操作数的偏移地址装入目的操作数。它的一般格式:

LEAREG16,MEMREG16表示一个16b通用寄存器,MEM是一个存储器操作数。上面指令把存储器操作数的偏移地址存入指定的16位寄存器。2.LEA(LoadEffectiveAddress,装载有效地址)指令假设变量X的偏移地址为1020H,(SI)=4455H,(EAX)=1200H,

(EBP)=20HLEADI,X

;执行后,(DI)=1020HLEABX,4[EBP*2][EAX] ;执行后,(BX)=4+20H×2+1200H

=1244H40[例2-1]编写程序,把4个元素的字节数组ARRAY清零。DATA SEGMENTARRAY DB 4DUP(?)DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATASTART: MOV AX,DATA MOV DS,AX MOV ARRAY,0 ;第一个元素清零

MOV ARRAY+1,0 ;第二个元素清零

MOV ARRAY+2,0 ;第三个元素清零

MOV ARRAY+3,0 ;第四个元素清零

MOV AX,4C00H INT 21HCODE ENDS END START41MOVAX,0LEABX,ARRAY

;数组ARRAY首地址装入BXMOVWORDPTR[BX],AX;第一、第二个元素清零MOVWORDPTR[BX+2],AX;第三、第四个元素清零一次将两个元素同时清零:MOVWORDPTRARRAY,0 ;第一、第二个元素清零MOVWORDPTRARRAY+2,0 ;第三、第四个元素清零使用立即数指令代码较长。把这个立即数事先存放在寄存器中:MOVAX,0MOVWORDPTRARRAY,AX ;第一、第二个元素清零MOVWORDPTRARRAY+2,AX;第三、第四个元素清零把数组ARRAY的首地址事先装入地址寄存器,程序更简捷:42[例2-2]字数组X的最后2个元素值送入Y数组对应单元DATA SEGMENT X DW 55,112,37,82 Y DW 4DUP(?)DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATASTART:MOVAX,DATA MOV DS,AX MOV DI,4 ;第三个元素在数组内的位移

MOV AX,X[DI] ;取出X数组第三个元素

MOV Y[DI],AX ;送入Y数组第三个元素中

MOV AX,X[DI+2] ;取出X数组第四个元素

MOV Y[DI+2],AX ;送入Y数组第四个元素中

MOV AX,4C00H INT 21HCODE ENDS END START432.2.4其他传送指令1.

地址传送指令LDS,LES,LFS,LGS[例]指令LDSSI,[BX]从DS:[BX]处取出32位二进制,两个低地址字节送入SI,两个高地址字节送入DS寄存器。指令执行后DS寄存器的内容被刷新。这些指令不影响标志位,LFS和LGS指令是80386开始增加的。地址传送指令从存储器取出4B,前面的2B送入指定的寄存器,

后面的2B送入由指令操作码包含的段寄存器。LDS REG16,MEM32;从存储器取出4B,送入REG16和DSLES REG16,MEM32;从存储器取出4B,送入REG16和ESLFS REG16,MEM32;从存储器取出4B,送入REG16和FSLGS REG16,MEM32;从存储器取出4B,送入REG16和GS44CBW ;将AL寄存器内容符号扩展成16b,送入AXCWD ;将AX寄存器内容符号扩展成32b,送入DX(高位)和AXCWDE;将AX寄存器内容符号扩展成32b,送入EAXCDQ ;将EAX寄存器内容符号扩展成64b,送入EDX和EAX2.

扩展传送指令MOVZX,MOVSX,CBW,CWD,CWDE,CDQ扩展传送指令把8位的操作数扩展为16/32位,或者把16位的操作数扩展为32位,送入目的寄存器。设有(EAX)=00008060HCBW;(AX)=0060HCWD;(DX)=0FFFFH,(AX)=8060HCWDE;(EAX)=0FFFF8060HCDQ;(EDX)=0000H,(EAX)=00008060H45设有(AX)=8060HMOVZX EBX,AX;(EBX)=00008060HMOVSX EBX,AX;(EBX)=0FFFF8060HMOVSX EBX,AL;(EBX)=00000060HMOVZX REG32/REG16,REG16/MEM16/REG8/MEM8

将16/8位寄存器/存储器操作数零扩展,送入32/16位寄存器MOVSX REG32/REG16,REG16/MEM16/REG8/MEM8

将16/8位寄存器/存储器操作数符号扩展,送入32/16位寄存器463.交换指令XCHG,SWAPXCHG REG/MEM,REG/MEM交换源、目的操作数的内容,两个操作数有相同的类型,不能同时为存储器操作数。

BSWAP REG32

交换32位寄存器的最高字节和最低字节、次高字节和次低字节例如,(EAX)=12345678HXCHG AH,AL ;(AX)=7856HBSWAP EAX ;(EAX)=78563412H474.

换码指令XLATXLAT MEM16

以MEM16对应段寄存器为段基址,以BX为偏移地址查表XLAT ;AL←DS:[BX+AL]用AL寄存器的内容查表,结果存回AL寄存器。表格的首地址事先存放在DS:BX中。48TABLE DB “0123456789ABCDEF” ……PUSH DS ;保护DS寄存器内容MOV BX,SEGTABLE ;取TABLE所在的段基址送BXMOV DS,BX ;从BX转送入DSLEA BX,TABLE ;取TABLE的偏移地址XLAT ;查表,(AL)=01000010B(’B’)POP DS ;恢复DS寄存器内容设(AL)=00001011B,下面程序执行后,AL中的二进制数改变为对应的十六进制数字符的ASCII代码01000010(’B’)。492.2.5堆栈堆栈(STACK)是用户使用的存储器的一部分,用来存放临时性的数据和其他信息,例如函数使用的局部变量、调用子程序的入口参数、返回地址等。堆栈的段基址必须放在SS中。堆栈段的“栈顶”地址(偏移地址)放在SP寄存器中。50在SEGMENT伪指令中增加“STACK”表示该段是“堆栈”。这个程序装入时,操作系统把SSEG的段基址置入SS,堆栈段的字节数(“栈底”位置,本例中为200=0C8H)置入SP。1.堆栈段结构

SSEGSEGMENTSTACK ;堆栈段开始

DW 100DUP(?) ;大小为100个字

SSEGENDS ;堆栈段结束堆栈段的定义:51从较大地址开始分配和使用(数据段、代码段从较小地址开

始分配和使用);由SP中地址指出的存储单元称为“栈顶”,数据总是在“栈顶”

位置存入(称为“压入”)、取出(称为“弹出”);最先进入的数据最后被弹出(FirstInLastOut,FILO),

最后进入的数据最先被弹出(LastInFirstOut,LIFO)堆栈段的特点:52压入2B数据的操作

SP←(SP)-2SS:[SP]←数据

弹出2B数据的操作目的操作数←SS:[SP]SP←(SP)+253ES,DS指向PSP;SS指向用户程序区;CS指向用户代码段

(由END伪指令指明);(SP)=0000H,指向64KB

存储器尾部。如果程序内未定义堆栈段,用户程序装入内存时:542.8086CPU堆栈指令PUSH(压栈)指令:把16b操作数压入堆栈PUSHREG16/MEM16/SEG指令的操作数是16b的寄存器、存储器、段寄存器。指令执行后,操作数的内容不变。552.8086CPU堆栈指令指令的操作数是16b的寄存器、存储器、段寄存器(CS除外)。指令执行后,操作数的内容被更新。把CS寄存器内容存入DS:POP(出栈)指令:从堆栈中弹出16b存入操作数POPREG16/MEM16/SEGPUSH CSPOP DS56PUSHFPOP AX ;AX←FlagsOR AX,0100H;将b8(TF位)置1PUSH AXPOPF ;Flags←AX

PUSHF指令把FLAGS寄存器内容压入堆栈。PUSHFPOPF指令从堆栈弹出16b送入FLAGS寄存器,指令执行后,各标志位被刷新。POPF下面程序段把TF标志位置位(置1):57LAHF指令把FLAGS寄存器的低8位送入AH寄存器LAHFSAHF指令把AH寄存器内容送入FLAGS寄存器的低8位,它的执行刷新了SF,ZF,AF,PF,CF标志位。SAHF583.扩展的堆栈指令80386开始的微处理器增设了32b的堆栈指令

PUSH REG32/MEM32;32位寄存器、存储器操作数压入堆栈

POP REG32/MEM32;从堆栈弹出32位二进制,送入操作数

PUSH IMM ;16/32位立即数压入堆栈立即数压入堆栈时,如果该立即数能够用16位二进制表述,则将这个立即数扩展为16位(对于无符号数进行零扩展,对于有符号数进行符号扩展),不能用16B表述的立即数扩展成32b压栈。59PUSHAD;把8个32位通用寄存器顺序压栈POPAD;从堆栈中弹出8个32b数据顺序存入通用寄存器80386增加了8个32位通用寄存器的入、出栈指令,顺序同上。80286微处理器增加了在一条指令中把8个通用寄存器压入、弹出堆栈的指令,压入的顺序是:AX、CX、DX、BX、SP、BP、SI、DI。注意,这里的SP代表指令执行之前的值。弹出的顺序相反。PUSHA;把8个16位通用寄存器顺序压栈POPA ;从堆栈中弹出8个16b数据,顺序存入通用寄存器上述指令执行都不影响标志位。60386开始新增了压入、弹出32位EFLAGS寄存器指令PUSHFD;把32位EFLAGS寄存器内容压入堆栈,原寄存器内容不变POPFD ;从堆栈中弹出32b,存入EFLAGS,寄存器内容被更新612.2.6 操作数表达式指令中的操作数,包括立即数和存储器操作数都可以用一个表达式来代替,这个表达式在汇编成目标的时候进行计算,它的结果用来产生目标代码。设变量X的偏移地址为1020HMOV AL,X+5MOV AL,[1025H]62汇编时,对EQU定义的符号名用对应的表达式进行“替换”。例如,有以下定义:1.

符号定义伪指令符号名 EQU 表达式NUM EQU 215MOD15ERR_MSG EQU “DataOverride”这些符号名使用的例子:MESSAGE DB ERR_MSG

;等价于MESSAGEDB“DataOverride”MOV CX,NUM+1

;等价于MOV CX,215MOD15+163POINTER EQU BUFFER[DI]WT EQU WORDPTRMOV BX,POINTER;等价于MOVBX,BUFFER[DI]MOV WTPOINTER,0 ;等价于MOVWORDPTRBUFFER[DI],0有以下定义:这些符号名使用的例子:64TIMES=0……TIMES=TIMES+1…… 使用“=”定义符号名时,只能使用常数表达式,而且对一个符号名可以多次定义。一个新的定义出现后,原来的定义自动终止。用EQU定义的符号名不允许重复定义。65“[]”称为“索引运算符”,用来括起组成有效地址的一个分量,各分量相加,得到最后的有效地址。2.地址表达式+,-运算符对构成有效地址的各个分量进行“加”、“减”操作。设变量X的偏移地址为1020H,存储器操作数X+5产生EA=1025H指令“MOV BL,X-10H”产生EA=1010H。MOV AX,2[BX][DI]MOV AX,[BX+DI+2]MOV AX,BUFFER[BX][2]MOV AX,[BUFFER+BX+2]663.

立即数表达式立即数表达式在汇编源程序时进行计算,它的结果用作指令中的立即数操作数。这种表达式中的运算对象必须是“已知”的,否则无法进行计算。用于产生立即数操作数的表达式有4类运算符: 算术运算符、逻辑运算符、关系运算符、地址运算符。67(1)算术运算符算术运算符+(相加),-(相减),*(相乘),/(整除运算),MOD(取余数)(*,/)→(MOD)→(+,-)运算优先级从高到低依次为可以使用圆括号改变运算顺序MOV BX,32+13/6MOD332+((13/6)MOD3)MOVBX,0022H34=22H68(2)逻辑运算符(SHL、SHR)→(NOT)→(AND)→(OR、XOR)30SHR115运算优先级从高到低依次为SHR(右移)、SHL(左移)、AND(逻辑与)OR(逻辑加)XOR(异或,半加)、NOT(逻辑非、取反)可以使用圆括号改变运算顺序69(3)关系运算符GT(大于)、GE(大于或等于)、LT(小于)、

LE(小于等于)、EQ(等于)、NE(不等于)关系运算符用于两个数的比较,结果为“真(-1)”或“假(0)”MOVAX,6000HGE5000HMOVAX,0FFFFHMOVEAX,–3GE2MOVEAX,00000000H70(4)地址运算符地址运算符对变量名、标号、地址表达式进行计算,得到作为立即数的运算结果

SEG取地址表达式所在段的段基址设变量LIST定义在DATA段中,

下面三条指令都是把DATA段的段基址装入AX:MOVAX,DATA ;DATA代表该段的段基址,是一个立即数MOVAX,SEGDATA;取DATA的段基址,结果是立即数MOVAX,SEGLIST;取LIST的段基址,结果是立即数71XDB “ABCDE” ;TYPE=1,LENGTH=1,SIZE=1YDW 3DUP(5),4DUP(-1) ;TYPE=2,LENGTH=3,SIZE=6ZDD 34,49,18 ;TYPE=4,LENGTH=1,SIZE=4OFFSET取地址表达式的偏移地址MOVAX,LIST ;取出变量LIST第一个元素送入AXMOVAX,OFFSETLIST ;取变量LIST的偏移地址送入AXTYPE、LENGTH、SIZE三个运算符分别用于取变量、标号的类型,取变量定义时的元素个数,取变量占用的字节数。近程标号的类型为-1、远程标号的类型为-272上面所有的表达式都必须是汇编期间可以求值的。“MOVAX,BX+2”是一条错误的指令,汇编时将报告错误,原因在于BX的值是未知的,可变的,在汇编阶段无法进行相关的计算。需要把BX的值与常数2相加并存入AX的操作只能在程序执行阶段由以下两条指令完成:MOV AX,BX ;BX寄存器值存入AX寄存器ADD AX,2 ;AX寄存器的值加上2,结果存入AX732.3汇编语言上机操作2.3.1编辑2.3.2汇编2.3.3连接2.3.4运行和调试74汇编语言源程序编制完成后,在计算机上的操作过程分为四个阶段:编辑、汇编、连接、运行调试752.3.1编辑输入源程序;对源程序进行修改。编辑阶段的主要任务是:一定要用“纯文本”格式来储存源程序文件,否则无法汇编。产生的源程序文件应该以“.ASM”或“.TXT”为扩展名,最好使用“.ASM”扩展名。大多数的文字编辑软件都可以用来输入和修改汇编语言源程序,如记事本(Notepad)、写字板(Writer)、Word以及命令行方式下的Edit(推荐使用)。762.3.2汇编汇编阶段的任务是把汇编语言源程序“翻译”成为机器代码(称为“目标”),产生二进制的“目标文件”。常用的汇编工具

Microsoft公司的MASM(MacroAssembler,宏汇编)

Borland公司的TASM(TurboAssembler)假设已经产生了一个汇编语言源程序文件“MYPRG1.ASM”,

可以用如下命令进行汇编:该命令正确执行后,将产生一个同名的目标文件MYPRG1.OBJ。TASM MYPRG1↙77如果汇编语言源程序文件以“.TXT”为扩展名,汇编时要使用这个文件的“全称”:TASM MYPRG1.TXT↙Errormessages:NoneWaringmessage:NoneTASM命令执行后,在屏幕上显示相关信息。说明这个程序已经顺利地通过了“汇编”,没有发现错误。**Error**EX2.ASM(14)Valueoutofrange……Errormessages:1表示汇编源程序EX2.ASM第14行有“数值超出范围”的错误,程序的错误总数为1。78/ZI产生用于程序调试的完整信息/L产生同名的列表文件完整的TASM命令行TASM[OPTION]SOURCE[,OBJECT][,LISTING][,XREF]↙[OPTION]这一部分可以给汇编过程提供一些可选择的项目。常用的选项有:[,OBJECT]通过这个选项另外指定目标文件名[,LISTING]用这个选项指定列表文件的名称[,XREF]这个选项用来产生交叉引用文件79对源程序“PRG.TXT”进行汇编,产生名为“PRG1.OBJ”的目标文件名为“PRG1.LST”的列表文件,同时产生程序调试所需要的完整信息(包含在目标文件中)。关于TASM命令更详细的信息,可以打入命令“TASM/?”获得。TASM/ZIPRG.TXT,PRG1,PRG1↙802.3.3连接连接阶段主要完成的操作是:把几个程序模块产生的目标文件连接成一个完整的可执行程序;把“子程序库”中的子程序连接到程序中去。由单个程序文件组成的简单程序,连接命令如下TLINKEX2↙对目标文件“EX2.OBJ”进行连接操作,产生同名的可执行程序“EX2.EXE”。

如果程序里没有定义堆栈段,连接过程会产生警告信息“Nostack”。如果程序比较小,这个警告信息不影响连接产生的可执行程序的使用。81/t产生“.COM”格式的可执行程序;/v产生的可执行程序包含全部的符号调试信息(汇编时已使用

过“/ZI”选项,否则该选项不起作用)。/3使用32位的寻址方式(例如,出现了指令“MOVAX,[EBX]”)可以在TLINK命令中增加一些选择项,常用的选择项:82TLINK

MYPRG1+MYPRG2,MYPRG,,MYLIB↙关于TLINK命令更详细的信息,可以打入命令“TLINK/?”获得。把目标文件MYPRG1.OBJ、MYPRG2.OBJ和子程序库文件MYLIB.LIB中的部分子程序连接成为一个可执行程序MYPRG.EXE。832.3.4运行和调试由TLINK产生的“.EXE”或者“.COM”文件可以直接执行。“MYPRG1↙”扩展名“.EXE”可以省略。如果同时存在文件MYPGM.EXE和MYPGM.COM,上面

的命令将执行程序MYPRG.COM而不是MYPGM.EXE。

如果同时存在文件MYPGM.EXE和MYPGM.COM,执行

程序MYPGM.EXE时,需要在命令行打入它的全名。84TASM5.0软件包中,用于程序调试的软件称为“TD”

(TurboDebugger):调试(Debug):在操作者的控制下执行这个程序,观察程序每个阶段的执行结果,或者修改参数反复运行程序,查找出程序中还存在的不正确的地方,或者验证程序的正确性。TDEX201↙汇编语言程序不包含输出结果的相关指令,操作者无法看到

程序的运行结果。程序能够运行,但是不能得到预想的结果。发生以下两种情况之一的,需要对程序进行“调试”。85调试程序“TD”的运行界面86TD的五个子窗口CPU子窗口:位于各窗口的左上方,占用面积最大,各列分别显示代码段的地址、内容、对应的符号指令(由代码段中的二进制机器指令“反汇编”得到)。数据子窗口:位于CPU子窗口的下方,显示部分存储器的内容。寄存器子窗口:显示各寄存器内容。可选择16/32位寄存器标志位子窗口:显示FLAGS寄存器内各标志位的当前值。堆栈子窗口

温馨提示

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

评论

0/150

提交评论