您的位置:首页 > 其它

MASM汇编语言笔记(三)数据传送和算术运算

2011-09-30 14:05 465 查看
三种类型的操作数:立即操作数immediate,寄存器操作数register,内存操作数memory

r8 8位通用寄存器:AH,AL,BH,BL,CH,CL,DH,DL

r16 16位通用寄存器:AX,BX,CX,DX,SI,DI,SP,BP

r32 32位通用寄存器:EAX,EBX,ECX,EDX,ESI,EDI,ESP,EBP

reg 任意通用寄存器

sreg 16位段寄存器:CS,DS,SS,ES,FS,GS

imm 8位,16位或32位立即数

imm8 8位立即数 字节

imm16 16位立即数 字

imm32 32位立即数 双字

r/m8 8位操作数:寄存器或内存

r/m16 16位操作数:寄存器或内存

r/m32 32位操作数:寄存器或内存

mem 8位,16位或32位内存操作数

直接内存操作数,下面的两种方式等价:

mov al,var1

mov al,[var1]

MOV指令

mov destination source

数据移动方向:左 <-- 右

遵循的规则:两个操作数尺寸一致,不能同时为内存操作数,目的操作数不能是CS,EIP和IP,立即数不能直接送往段寄存器

保护模式下程序一般不操作段寄存器

整数的零/符号扩展

16位-->32位,一般先清零ECX(对负数不适用),例如:

.data

count word 1

.code

mov ecx,0

mov cx,count

MOVZX move with zero-extend 零扩展传送,仅适用于无符号整数,规则:

movzx r32,r/m8 movzx r32,r/m16 movzx r16 r/m8

例如:

mov bx,0a69bh

movzx eax,bx

movzx edx,bl

movzx cx,bl

MOVSX move with sign-extend 符号扩展传送,仅适用于有符号整数,规则同MOVZX

符号扩展方法是:用较小操作数的最高位循环填充目的操作数的扩展位

LAHF load status flags into AH将EFLAGS寄存器的低字节复制到AH寄存器,被复制的标志包括:

符号标志,零标志,辅助进位标志,奇偶标志,进位标志

SAHF store AH into status flags与LAHF相反的操作

XCHG exchange data 交换两个操作数的内容,遵循MOV指令相同的规则,但不接受立即数

交换两个内存操作数时,需要使用一个寄存器作为临时存储容器,例如:

mov ax,val1

xchg ax,val2

mov val1,ax

直接偏移操作数

变量后加偏移值,direct-offset,访问没有标号的内存地址,例如:

array BYTE 10h,20h,30h,40h,50h

mov al,array ;AL=10h

mov al,[array+1] ;AL=20h

mov al,array+2 ;AL=30h

注意:MASM不进行索引范围检查

字数组需加2才能访问第二个元素,双字需加4才能访问第二个元素

加法和减法

INC和DEC指令 INC increase 加1 DEC decrease 减1

inc reg/mem dec reg/mem

ADD和SUB 不改变源操作数,结果存储在目的操作数中

影响的标志:进位标志,零标志,符号标志,溢出标志,辅助进位标志,奇偶标志

NEG negate 求补码(求补码的方法:所有位取反后加1)

进位标志用于表示 无符号整数 是否发生了溢出

溢出标志用于表示 有符号整数 运算是否发生了溢出

零标志用于表示运算结果是否为零

符号标志用于表示运算结果是否为负(最高有效位为1)

奇偶标志用于表示最低有效字节内1的个数是否为偶数

辅助进位标志用于表示运算结果的最低有效字节的第三位是否向高位进位(主要用于BCD算术运算)

数据相关的操作符和伪指令

OFFSET 返回变量相对段起始的偏移

PTR 重载变量默认尺寸,例如:

.data

myDouble DWORD 12345678h

.code

mov ax,WORD PTR myDouble ;正确

mov ax,myDouble ;错误

TYPE 返回数组中每个元素的大小,以字节计算

LENGTHOF返回数组内元素的数目

SIZEOF 返回数组初始化时占用的字节数

ALIGN 对齐变量边界,按字节,字,双字

LABEL 插入标号,不分配实际存储空间

间接寻址

indirect addressing

间接操作数 indirect operand

保护模式的间接操作数可以是方括号括起来的任意32位通用寄存器,寄存器里存放数据偏移地址,例如:

.data

val BYTE 10h

.code

mov esi,OFFSET val

mov al,[esi] ;AL=10h

这样也可以:mov [esi],bl

实模式下只能使用16位寄存器存放变量偏移地址,而且只能使用SI,DI,BX,BP,最好不使用BP,例如:

.data

val BYTE 10h

.code

main proc

startup

mov si,OFFSET val

mov al,[si] ;AL=10h

变址操作数

indexed operand

把常量和寄存器相加得到一个有效地址,访问数组元素前,寄存器使用前应初始化为0,例如:

.data

arrayB BYTE 10h,20h,30h

.code

mov esi,0

mov al,[arrayB+esi] ;AL=10h

加偏移地址,例如:mov ax,[esi+4]

变址操作数,比例因子scale factor计算偏移,例如:

.data

arrayD DWORD 100h,200h,300h,400h

.code

mov esi,3*TYPE arrayD

mov eax,arrayD[esi] ;EAX=400h

指针 pointer variable

两种类型

NEAR指针:相对段开始的32(16)位偏移地址

FAR指针:48位的段选择子-偏移地址(32位的段-偏移地址)

TYPEDEF操作符:定义自定义类型,例如定义指针:

PBYTE TYPEDEF PTR BYTE

.data

arrayB BYTE 10h,20h,30h,40h

ptr1 PBYTE ? ;未初始化

ptr2 PBYTE arrayB ;指向数组

JMP 无条件跳转指令

LOOP指令 重复执行语句块,ECX作计数器,每次循环后减1

(LOOPD总是用ECX作计数器,LOOPW总是用CX作计数器)

循环目的地址与当前地址要在相距-128~+127范围内

循环开始保存ECX寄存器,循环结束恢复ECX寄存器的值
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: