1.传送指令mov
·双操作数指令的目的操作数与源操作数必须类型一致
·要求类型一致的两个操作数之一必须有明确的类型 否则用ptr
·双操作数指令(除了特别说明)不允许两个操作数都是存储单元
·能对专用寄存器进行操作的指令有限,功能不强
mov al,050ah ;错误,类型不一致 050a超出了寄存器al的范围
mov eax,050ah ;正确,双字量传送
mov esi,dl ;错误,类型不一致 esi为32位 dl为8位
mov 【ebx】,255 ;错误 无明确类型
mov byte ptr 【ebx】,255 ;正确
mov word ptr 【ebx】,255 ;正确
mov dword ptr 【ebx】,255 ;正确
假设dbuf1和dbuf2是两个双字变量
mov dbuf1,dbuf2 ;错误,两个操作数都是存储单元
mov eax,dbuf1
mov dbuf2,eax
2.交换指令XCHG
交换源操作数与目的操作数的内容,可以在通用寄存器与通用寄存器或存储器之间对换数据,但是不能在存储器与存储器之间对换数据
数据交换程序
; eg3.7.asm in Windows Console
include io32.inc
.data
num byte 6,7,7,8,3,0,0,0,0,0
tab byte ‘yunfeiyang’
.code
start:
mov ecx,lengthof num ;ecx=变量num的长度
mov esi,offset num ;esi指向变量num
mov edi,offset tab ;edi指向变量tab
again:
mov al,[esi] ;al获得变量num的一个数字 al=[esi]=6
xchg al,[edi] ;交换,al等于变量tab对应的字符 交换后:al=y [edi]=6
mov [esi],al ;保存回变量num原位置 [esi]=al=y
call dispc ;显示al中的字符
call dispcrlf
add esi,1 ;esi指针+1,指向下一个数字
add edi,1 ;edi指针+1,指向下一个字符
loop again ;循环处理 循环操作指令,它先将本指令默认使用的计数器ecx-1,如果ecx不等于0,则循环没结束,程序跳转到loop 指令所指定的标号位置执行那里的指令
xchg eax,eax ;不明白这个指令的意义
调用disprd显示eax:
不明白有什么用
nop ;no operation 空操作指令 处理器执行该指令需要花费时间,且放置在主存中也要占用一个字节空间,编程中,有时利用nop指令实现短时间延时,还可以临时占用代码空间以便以后填入需要的指令代码
exit 0
end start
或者:
将代码段改为:
mov ecx,lengthof num
mov esi,0
again:
mov al,num[esi] ;寄存器相对寻址 没改之前是寄存器间接寻址
xchg al,tab[esi]
mov num[esi],al
call dispc
add esi,1
loop again
堆栈操作指令
1.进栈指令PUSH
先将esp减小作为当前栈顶(腾出空间),然后将立即数,通用寄存器和段寄存器内容或存储器操作数存进去
格式:
push src
2.出栈指令POP
先将栈顶数据传送到通用寄存器、存储单元或段寄存器中,,然后ESP增加作为当前栈顶。(先从栈顶传出去一个,再加2(假如是字量数据出栈)(即栈顶上移))
格式:
POP dest
堆栈操作程序
; eg3.8.asm in Windows Console
include io32.inc
.data
ten=10
dvar dword 67762000h,12345678h
.code
start:
mov eax,dvar+4 ;eax=12345678h
push eax ;压栈 栈顶数据12345678h 进栈时的栈顶
push dword ptr ten ;压栈 0000000A
push dvar ;压栈 67762000h
pop eax ;出栈,将栈顶数据(67762000h)传送到eax 出栈时的栈顶
pop dvar+4 ;出栈,栈顶数据(0000000A)传送给dvar+4 传送到eax
mov ebx,dvar+4 ;ebx=0000000AH
pop ecx ;ecx=12345678H
call disprd
exit 0
end start
堆栈的应用
利用堆栈实现主程序与子程序间的参数传递
mov ebp,esp
mov eax,[ebp+8]
mov [ebp],eax
其他传送指令
1.换码指令 XLAT
换码显示程序
; eg3.9.asm in Windows Console
include io32.inc
.data
num byte 6,7,7,8,3,0,0
tab byte ‘yunfeiyang’
.code
start:
mov ecx,lengthof num
mov esi,offset num ;esi指向num
mov ebx,offset tab ;ebx指向tab
again:
mov al,[esi] ;al=6
xlat ;AL←[EBX+AL] 即AL=[ebx+6]
call dispc
add esi,1 ;esi+1 指向下一个字母
loop again ;循环
exit 0
end start
;第二次时:al=7 xlat:al=ebx+7 是a
;第三次时:al=7 xlat:al=ebx+7 是a
;第四次时:al=8 xlat:al=ebx+8 是n
;第五次时:al=3 xlat:al=ebx+3 是f
;…….
xlat只能进行字节量表格换码,可以用循环指令代替它
again:
mov eax,0
mov al,[esi]
add eax,ebx ;eax=eax+ebx
mov al,[eax]
call dispc
add esi,1
loop again
2.标志传送指令
*待添加*
3.地址传送指令
获取有效地址指令:LEA
地址传送程序
;eg3.10.asm in Windows Console
include io32.inc
.data
dvar dword 41424344h
.code
start:
mov eax,dvar ;eax=dvar
lea esi,dvar ;esi指向dvar
mov ebx,[esi] ;ebx=dvar
mov edi,offset dvar ;edi指向dvar
mov ecx,[edi] ;ecx=dvar
lea edx,[esi+edi4+100h] ;edx=esi+edi4+100h 先进性加法运算得到偏移地址,再传给edx
call disprd
exit 0
end start