【汇编的简单操作】

汇编的基本操作

汇编的学习方法就是多看,多写,注意细节。我用的汇编工具是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++代码,将其写成汇编语言,以上就是今天要讲的内容。
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值