汇编的基本操作
汇编的学习方法就是多看,多写,注意细节。我用的汇编工具是EditPlus 2
一、汇编模板
总体:
include irvine32.inc
.data
;定义全局变量
.code
;代码区
函数模块:
函数名 proc
ret
函数名 endp
定义全局变量:
1.定义数字
num=3
num dd 3
不赋值
num dd ?
2.定义字符串
msg=“我爱学习”
msg db ‘我爱学习’,0
3.定义数组
int t1[90];
int t2[90]={0};
t1 dd 90 dup(?)
t2 dd 90 dup(0)
二、寄存器
寄存器是用于存放程序和执行过程中的代码和数据的存储单元。
IA-32里有8个32位通用寄存器:EAX,EBX,ECX,EDX,ESI,EDI,EBP,ESP;1个32位标志寄存器EFLAGS和1个32位指令指针寄存器EIP。有8个16位通用寄存器AX,BX,CX,DX,SI,DI,BP,SP,分别表示相应32位寄存器低16位部分。其中前四个还可以分成高字节H和低字节L,又可以有8个8位通用寄存器:AH,AL,BH,BL,CH,CL,DH,DL>
常用指令
数据转移指令:
c中指令为:a=6
mov eax,6
或是
mov eax,ebx
比较指令:
//c
if(a>b)
{c1语句}
else
{c2语句}
cmp eax,ebx;比较eax,ebx
jg L;如果eax>ebx,则跳转到L,否则继续向下执行C2语句
c2语句;c2结尾也要有跳转,否则执行完C2也会继续向下执行c1语句
L:c1语句
跳转指令:
jmp、jXXX
函数调用指令:
call XXX
输入数字:
call readint
此时输入的数字保存在EAX寄存器中
输出数字:
输出的是EAX里的数字
1.有符号
call writeint
2.无符号
call writedec
输出字符串
输出的是EDX里的字符串
call writestring
加法:eax=eax+ebx
add eax,ebx
减法:eax=eax-ebx
sub eax,ebx
乘法:eax=eax*ecx
mul ecx
除法:eax=eax/ecx
除法余数存在EAX中,商存在EDX中,在除法算数之前要将EDX置为0
mov edx,0
div ecx
如果要输出语句,可先在全局变量中定义,再输出
如输出“我爱学习”
.data
msg db '我爱学习',0
.code
main proc
mov edx,offset msg
call writestrinf
exit
main end
end main
快速排序
//c
void print(int a[], int n){
for(int j= 0; j<n; j++){
cout<<a[j] <<" ";
}
cout<<endl;
}
void swap(int *a, int *b){
int tmp = *a;
*a = *b;
*b = tmp;
}
int partition(int a[], int low, int high){
int Key = a[low]; //基准元素
while(low < high){ //从表的两端交替地向中间扫描
while(low < high && a[high] >= Key) --high;
//从high 所指位置向前搜索,至多到low+1 位置。
//将比基准元素小的交换到低端
swap(&a[low], &a[high]);
while(low < high && a[low] <= Key ) ++low;
swap(&a[low], &a[high]);
}
print(a,10);
return low;
}
void quickSort(int a[], int low, int high){
if(low < high){
int Loc = partition(a, low, high); //将表一分为二
quickSort(a, low, Loc -1); //递归对低子表递归排序
quickSort(a, Loc + 1, high); //递归对高子表递归排序
}
}
int main(){
int a[10] = {3,1,5,7,2,4,9,6,10,8};
cout<<"初始值:";
print(a,10);
quickSort(a,0,9);
cout<<"结果:";
print(a,10);
}
//汇编代码
include irvine32.inc
.data
ten dd 10
a dd 3,1,5,7,2,4,9,6,10,8
nine dd 9
zero dd 0
msg1 db '初始值:',0
msg2 db '结果:',0
msg3 db 'swap',0
msg4 db 'partition',0
.code
main proc
lea edx,offset msg1
call writestring
;lea esi,a
push offset a
push ten
call print
push offset a
push zero
push nine
call quickSort
lea edx,offset msg2
call writestring
push offset a
push ten
call print
exit
main endp
;push offset a
;push n
;call print
;return nothing
print proc
push ebp
mov ebp,esp
pushad
mov edx,[ebp+12]
mov ebx,[ebp+8];n=ebx
mov ecx,0;i=ecx
again: cmp ecx,ebx
jge final
mov eax,[edx+4*ecx]
call writeint
mov al,' '
call writechar
inc ecx
jmp again
final:
call crlf
popad
pop ebp
ret 8
print endp
swap proc
push ebp
mov ebp,esp
pushad
;lea edx,offset msg3
;call writestring
mov ecx,[ebp+12];ecx=a
mov edx,[ebp+8];edx=b
mov eax,[ecx]
mov ebx,dword ptr[edx]
mov [ecx],ebx
mov dword ptr[edx],eax
popad
pop ebp
ret 8
swap endp
partition proc
push ebp
mov ebp,esp
sub esp,4
pushad
mov ebx,[ebp+16]
mov ecx,[ebp+12];ecx=low
mov edx,[ebp+8];edx=high
mov eax,[ebx+4*ecx];eax=key
outlin: cmp ecx,edx
jge final
first: cmp ecx,edx
jge swap1
cmp dword ptr[ebx+4*edx],eax
jge sub1
jmp swap1
sub1: sub edx,1
jmp first
swap1:
lea esi,[ebx+4*ecx]
push esi
lea esi,[ebx+4*edx]
push esi
call swap
jmp second
second: cmp ecx,edx
jge swap2
cmp eax,dword ptr[ebx+4*ecx];a[low]
jge add1
jmp swap2
add1: add ecx,1
jmp second
swap2: lea esi,[ebx+4*ecx]
push esi
lea esi,[ebx+4*edx]
push esi
call swap
jmp outlin
final: push ebx
push ten
call print
mov [ebp-4],ecx
popad
mov eax,[ebp-4]
add esp,4
pop ebp
ret 12
partition endp
;push a
;push low
;push high
;call quickSort
;retrun void
quickSort proc
push ebp
mov ebp,esp
pushad
mov ebx,[ebp+16];ebx=a
mov ecx,[ebp+12];ecx=low
mov edx,[ebp+8];edx=high
cmp ecx,edx
jge final
push ebx
push ecx
push edx
call partition
;mov esi,eax
push eax
sub eax,1
push ebx
push ecx
push eax
call quickSort
;mov esi,eax
pop eax
add eax,1
push ebx
push eax
push edx
call quickSort
final: popad
pop ebp
ret 12
quickSort endp
end main
编程实现输出{1,2,…,n}个数全排列
void print(int a[], int n){
for(int j= 0; j<n; j++){
cout<<a[j] <<" ";
}
cout<<endl;
}
void swap(int *a, int *b){
int tmp = *a;
*a = *b;
*b = tmp;
}
int partition(int a[], int low, int high){
int Key = a[low]; //基准元素
while(low < high){ //从表的两端交替地向中间扫描
while(low < high && a[high] >= Key) --high;
//从high 所指位置向前搜索,至多到low+1 位置。
//将比基准元素小的交换到低端
swap(&a[low], &a[high]);
while(low < high && a[low] <= Key ) ++low;
swap(&a[low], &a[high]);
}
print(a,10);
return low;
}
void quickSort(int a[], int low, int high){
if(low < high){
int Loc = partition(a, low, high); //将表一分为二
quickSort(a, low, Loc -1); //递归对低子表递归排序
quickSort(a, Loc + 1, high); //递归对高子表递归排序
}
}
int main(){
int a[10] = {3,1,5,7,2,4,9,6,10,8};
cout<<"初始值:";
print(a,10);
quickSort(a,0,9);
cout<<"结果:";
print(a,10);
}
//汇编
include irvine32.inc
.data
ten dd 10
a dd 3,1,5,7,2,4,9,6,10,8
nine dd 9
zero dd 0
msg1 db '初始值:',0
msg2 db '结果:',0
msg3 db 'swap',0
msg4 db 'partition',0
.code
main proc
lea edx,offset msg1
call writestring
;lea esi,a
push offset a
push ten
call print
push offset a
push zero
push nine
call quickSort
lea edx,offset msg2
call writestring
push offset a
push ten
call print
exit
main endp
;push offset a
;push n
;call print
;return nothing
print proc
push ebp
mov ebp,esp
pushad
mov edx,[ebp+12]
mov ebx,[ebp+8];n=ebx
mov ecx,0;i=ecx
again: cmp ecx,ebx
jge final
mov eax,[edx+4*ecx]
call writeint
mov al,' '
call writechar
inc ecx
jmp again
final:
call crlf
popad
pop ebp
ret 8
print endp
swap proc
push ebp
mov ebp,esp
pushad
;lea edx,offset msg3
;call writestring
mov ecx,[ebp+12];ecx=a
mov edx,[ebp+8];edx=b
mov eax,[ecx]
mov ebx,dword ptr[edx]
mov [ecx],ebx
mov dword ptr[edx],eax
popad
pop ebp
ret 8
swap endp
partition proc
push ebp
mov ebp,esp
sub esp,4
pushad
mov ebx,[ebp+16]
mov ecx,[ebp+12];ecx=low
mov edx,[ebp+8];edx=high
mov eax,[ebx+4*ecx];eax=key
outlin: cmp ecx,edx
jge final
first: cmp ecx,edx
jge swap1
cmp dword ptr[ebx+4*edx],eax
jge sub1
jmp swap1
sub1: sub edx,1
jmp first
swap1:
lea esi,[ebx+4*ecx]
push esi
lea esi,[ebx+4*edx]
push esi
call swap
jmp second
second: cmp ecx,edx
jge swap2
cmp eax,dword ptr[ebx+4*ecx];a[low]
jge add1
jmp swap2
add1: add ecx,1
jmp second
swap2: lea esi,[ebx+4*ecx]
push esi
lea esi,[ebx+4*edx]
push esi
call swap
jmp outlin
final: push ebx
push ten
call print
mov [ebp-4],ecx
popad
mov eax,[ebp-4]
add esp,4
pop ebp
ret 12
partition endp
;push a
;push low
;push high
;call quickSort
;retrun void
quickSort proc
push ebp
mov ebp,esp
pushad
mov ebx,[ebp+16];ebx=a
mov ecx,[ebp+12];ecx=low
mov edx,[ebp+8];edx=high
cmp ecx,edx
jge final
push ebx
push ecx
push edx
call partition
;mov esi,eax
push eax
sub eax,1
push ebx
push ecx
push eax
call quickSort
;mov esi,eax
pop eax
add eax,1
push ebx
push eax
push edx
call quickSort
final: popad
pop ebp
ret 12
quickSort endp
end main
迷宫问题
//c
#include<stdio.h>
#define R 7 //行;
#define C 8 //列;
int M[R+2][C+2]= //迷宫'1'表示墙,'0'表示路;
{
//0 1 2 3 4 5 6 7 8 9
/*0*/1,1,1,1,1,1,1,1,1,1,
/*1*/1,0,0,0,1,1,1,1,1,1,
/*2*/1,0,1,0,1,1,1,1,1,1,
/*3*/1,0,0,0,1,1,1,1,1,1,
/*4*/1,1,1,0,0,0,0,1,1,1,
/*5*/1,1,1,1,0,1,1,1,1,1,
/*6*/1,1,1,1,0,0,0,1,1,1,
/*7*/1,1,1,1,1,1,0,0,0,1,
/*8*/1,1,1,1,1,1,1,1,1,1
};
int t[R+2][C+2]={0}; //与迷宫相同的二维数组,用来表示该条路有没有走;
int Move[4][2]= //记录走的方向;
{
{1,0}, //向南走;
{0,1}, //向东走;
{-1,0}, //向北走;
{0,-1} //向西走;
};
int stack[100][2]; //用来存放路径的栈;
int top;
int sum=0;
//输出;
void Print(int sum)
{
printf("迷宫的第%d条路径如下:\n",sum);
for(int i=0;i<=top;i++)
printf("(%d,%d)->",stack[i][0],stack[i][1]);
printf("出口");
printf("\n");
}
//调用迷宫函数;
void Maze(int x,int y)
{
if(x==7&&y==8)
{
sum++;
Print(sum);
}
else
{
for(int i=0;i<4;i++) //遍历四个方向;
{
int a=x+Move[i][0]; //找到下一个要走位置的x;
int b=y+Move[i][1]; //找到下一个要走位置的y;
if(!M[a][b]&&!t[a][b]) //判断这个位置可不可以走;
{
t[a][b]=M[a][b]=1; //用数组t,M记录这个位置已经走过了;
top++; //将top++用来存储下一个位置坐标;
stack[top][0]=a; //将横坐标x存入stack数组中;
stack[top][1]=b; //将纵坐标y存入stack数组中;
Maze(a,b); //继续寻找下一个位置;
t[a][b]=M[a][b]=0; //回溯之后需要将这个位置清空,表示这条路没有走过;
top--; //并且将这个位置从栈中去除;
}
}
}
}
int main(void)
{
//迷宫初始化;
stack[0][0]=1; //存放起点的x,y的坐标;
stack[0][1]=1;
top=0; //top++表示已经存放了开始坐标;
t[1][1]=M[1][1]=1; //表示第一个位置已经走过了;
Maze(1,1);
return 0;
}
//汇编代码
include irvine32.inc
.data
R dd 7
cc dd 8
M dd 1,1,1,1,1,1,1,1,1,1
dd 1,0,0,0,1,1,1,1,1,1
dd 1,0,1,0,1,1,1,1,1,1
dd 1,0,0,0,1,1,1,1,1,1
dd 1,1,1,0,0,0,0,1,1,1
dd 1,1,1,1,0,1,1,1,1,1
dd 1,1,1,1,0,0,0,1,1,1
dd 1,1,1,1,1,1,0,0,0,1
dd 1,1,1,1,1,1,1,1,1,1
t dd 90 dup(0)
Move dd 1,0
dd 0,1
dd -1,0
dd 0,-1
stack1 dd 200 dup(0)
top dd 0
sum dd 0
four dd 4
zero dd 0
forty dd 40
msg1 db '迷宫的第',0
msg2 db '条路径如下',0
msg3 db '(',0
msg4 db ',',0
msg5 db ')->',0
msg6 db '出口',0
.code
main proc
mov eax,1
mov [stack1],eax
mov [stack1+4],eax
mov eax,0
mov top,eax
mov eax,1
mov [t+44],eax
mov [M+44],eax
push 1
push 1
call Maze
exit
main endp
;push sum
;call Print
Print proc
push ebp
mov ebp,esp
pushad
mov ebx,[ebp+8];ebx=sum
mov edx,offset msg1
call writestring
mov eax,ebx
call writedec
mov edx,offset msg2
call writestring
call crlf
mov ecx,0
mov esi,top
cyc: cmp ecx,esi
jg final
mov edi,ecx
shl edi,3
mov edx,offset msg3
call writestring
mov eax,[stack1+edi]
call writedec
mov edx,offset msg4
call writestring
mov eax,[stack1+edi+4]
call writedec
mov edx,offset msg5
call writestring
inc ecx
jmp cyc
final:
mov edx,offset msg6
call writestring
call crlf
popad
pop ebp
ret 4
Print endp
;push x
;push y
;call Maze
Maze proc
push ebp
mov ebp,esp
sub esp,16
pushad
mov ebx,[ebp+12];ebx=x
mov ecx,[ebp+8];ecx=y
cmp ebx,R
jne jud2
cmp ecx,cc
jne jud2
add sum,1
push sum
call Print
jmp final
jud2:
mov esi,0;esi=i
cyc: cmp esi,four
jge final
mov edi,esi
shl edi,3
mov eax,[Move+edi];eax=Move[i][0]
add eax,ebx;eax=a=x+Move[i][0]
mov [ebp-8],eax;[ebp-8]=a
mov [ebp-12],eax;[ebp-12]=a
mov eax,[Move+edi+4]
add eax,ecx
mov [ebp-4],eax;[ebp-4]=b
mov edi,eax;edi=b
mov [ebp-16],eax;[ebp-16]=b
mov eax,[ebp-8]
mul forty
mov edx,[M+eax+4*edi]
mov [ebp-8],edx;[ebp-8]=M[a][b]
mov edx,[t+eax+4*edi]
mov [ebp-4],edx;[ebp-4]=t[a][b]
mov edx,zero
cmp [ebp-8],edx
jne cont1
cmp [ebp-4],edx
jne cont1
push ecx
push eax
mov eax,[ebp-12]
mul forty
mov edi,[ebp-16]
mov ecx,1
mov [M+eax+4*edi],ecx
mov [t+eax+4*edi],ecx
pop eax
pop ecx
add top,1
mov edx,top
shl edx,3
push eax
mov eax,[ebp-12]
mov [stack1+edx],eax
mov eax,[ebp-16]
mov [stack1+edx+4],eax
pop eax
push [ebp-12]
push [ebp-16]
call Maze
push eax
push ecx
mov eax,[ebp-12]
mul forty
mov edi,[ebp-16]
mov ecx,0
mov [M+eax+4*edi],ecx
mov [t+eax+4*edi],ecx
pop ecx
pop eax
sub top,1
cont1:
inc esi
jmp cyc
final:
popad
add esp,16
pop ebp
ret 8
Maze endp
end main
总结
汇编的多练也可以是在网上、书上找c/c++代码,将其写成汇编语言,以上就是今天要讲的内容。