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

 

三种类型的操作数:立即操作数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寄存器的值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值