微机原理复习

更新时间:2024-01-02 01:40:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

1.; Win32 Console Application

; 目的:学习如何利用条件转移指令构造复杂逻辑运算结构。 ; 算法描述

; esi=0;ecx=2012; ; while (ecx<2100)

; { if (year mod 4=0 and year mod 100 <>0) or (year mod 400=0) then ; {Lyear[esi]=ecx;esi++;} ; ecx++; ; }

; Lcounter=esi;

; 采用div指令求余数来判断整除性,采用带比例因子的相对寻址处理数组。 include io32.inc .data

Lyear dword 100 dup(?) Lcounter dword 0 .code

main proc

xor esi,esi ;esi闰年个数计数器,兼做Lyear下标。 mov ecx,2012 ;ecx年份计数器。 .while (ecx<2100)

mov eax,ecx xor edx,edx mov ebx,400 div ebx cmp edx,0 jz leap ;if year mod 400=0 then goto leap mov eax,ecx xor edx,edx mov ebx,4 div ebx Cmp edx,0 jnz next ;if year mod 4<>0 then goto next Mov eax,ecx Xor edx,edx mov ebx,100 div ebx cmp edx,0 jz next ;if year mod 100=0 then goto next leap: mov Lyear[esi*4],ecx inc esi mov eax,ecx call dispuid ;输出,用于验证。可以删掉 call dispcrlf ;输出,用于验证。可以删掉 next: inc ecx

.endw

Mov Lcounter,esi mov eax,esi call dispuid ;输出,用于验证。可以删掉 call dispcrlf ;输出,用于验证。可以删掉 ret

main endp ;end of main end main ;end of assembly

2.; Win32 Console Application ; 求2~100之间的所有素数。

; 目的:学习如何利用条件转移指令构造条件循环结构,多重循环的构造方法。 ; 采用伪代码pseudo code描述算法 ; 1. i=2 to 100 do

; 1.1 if i is prime number then print i ; 细化 1.1 如下: ; 1.1 j=2 to i/2 do

; 1.1.1 if i mod j=0 then goto next i ; 1.1.2 print i

; 合理分配寄存器,i=ebx,j=ecx,edxeax做被除数,ecx做除数. ; 学习如何构造计数循环,条件循环。

; Q:计数循环的初值大于终值时如何处理???

include io32.inc .data msg byte ' List of prime number',13,10,0 msg1 byte ' Lcounter is :' ,13,10,0 blank byte ' ',0

prime dword 100 dup(?) pcounter dword 0 .code

main proc ;主程序开始 mov esi,0 mov eax,offset msg call dispmsg mov ebx,2 iLoop: cmp ebx,100 ;i循环入口 ja done mov ecx,ebx shr ecx,1 ;j=i/2 jLoop: cmp ecx,2 ;j循环入口 jb print mov eax,ebx

cdq ;xor edx,edx div ecx ;被除数送eax,32位除法 or edx,edx ;cmp edx,0 jz nexti ;if i mod j=0 then goto next i dec ecx jmp jLoop

print: mov prime[esi*4],ebx inc esi mov eax,ebx

call dispuid ;输出,用于验证。可以删掉 ;输 ;显示素数i的值 mov eax,offset blank call dispmsg ;显示空格 nexti: inc ebx ;i=i+1 jmp iLoop done: call dispcrlf mov eax,offset msg1 call dispmsg mov pcounter,esi mov eax,esi call dispuid call dispcrlf ret ;返回操作系统 main endp ;主程序结束 end main ;end of assembly 3.; bubble.asm ,bubble sort

; 采用伪代码pseudo code描述算法 ; 1. i=n-1 downto 1 do ; 1.1 j=0 to i-1

; 1.1.1 if a[j]>a[j+1] then swap

; 合理分配寄存器,i=ecx,j=edx ,i-1=ecx-1

; 汇编语言中只有常量表达式! 技巧:dec ecx/inc ecx ; 学习如何构造计数循环,条件循环

; Q:计数循环的初值大于终值时如何处理??? include io32.inc

.data ;set data segment

;TODO: Place Global Variables and constant here blank3 byte 3 dup(20h),0 array dword 12,4,-168,122,33,56,78,99,345,-66,-5 char byte ?

msg byte 13,10,'press any key to continue ...',0 ;字符串 .code

main proc

;TODO: Place code here

mov ecx,(lengthof array)-1 ;计数循环的初值 iLoop: ;i循环入口 dec ecx ;ecx=i-1 xor edx,edx jLoop: ;j循环入口,循环控制变量edx cmp edx,ecx jg nexti

mov eax,array[edx*4] cmp eax,array[edx*4+4] jge nextj

xchg eax,array[edx*4+4] mov array[edx*4],eax nextj: inc edx jmp jLoop nexti: inc ecx ;retrieve ecx loop iLoop

print: xor ecx,ecx again: cmp ecx,lengthof array-1 jg done

mov eax,array[ecx*4] call dispsid

mov eax,offset blank3 ;显示空格 call dispmsg inc ecx jmp again

done: mov eax,offset msg ;显示:press any key to continue call dispmsg

mov eax,offset char ;暂停,等待按任意键 call readc

ret ;返回操作系统 main endp

end main ;end of assembly 4. ; Win32 Console Application ; find max,min .686

.model flat,stdcall

option casemap:none ;case sensitive 大小写敏感

includelib msvcrt.lib ; C语言中的 stdio.h conio.h 的动态链接库 ; C语言库函数的原型说明

printf PROTO C : dword,:vararg scanf PROTO C : dword,:vararg .data ;set data segment ara dword 12,4,-168,122,33,56,78,99,345,-66,-5

max dword ? min dword ? prompt byte 'Enter an integers :',0 maxStr byte 'max=%d',13,10,0 ;显示字符串的格式描述串 minStr byte 'min=%d',13,10,0 .code

main proc

mov ecx,lengthof ara -1 mov eax,ara[0] ;eax:max mov ebx,eax ;ebx,min mov esi,1 again: cmp eax,ara[esi*4] jge small mov eax,ara[esi*4] small: cmp ebx,ara[esi*4] jle next mov ebx,ara[esi*4] next: inc esi loop again mov max,eax mov min,ebx

invoke printf,offset maxStr,eax invoke printf,offset minStr,ebx

ret ;返回操作系统 main endp

end main 5. include io32.inc .data

msg byte 'I love XUT!',13,10,0 space dword ? char dword ? .code main proc mov ebx,0 xor edi,edi mov esi,edi

l1:mov al,msg[ebx] cmp al,20h jnz done1 cmp al,0 jz next inc edi inc ebx jmp l1

done1: cmp al,'a' jb done2 cmp al,'z' ja done2 cmp al,0 jz next inc esi inc ebx jmp l1

done2:cmp al,0 jz next inc ebx jmp l1 next:

mov space,edi mov eax,space call dispuid call dispcrlf mov char,esi mov eax,char call dispuid call dispcrlf ret

main endp end main

6. include io32.inc .data

msg byte 'I love XUT!',13,10,0 .code main proc mov ebx,0

l1:mov al,msg[ebx] cmp al,'a' jb done cmp al,'z' ja done sub al,20h done: cmp al,0 jz done1 inc ebx call dispc jmp l1 done1: ret

main endp end main

7. ; Win32 Console Application ; 求数组中所有偶数元素的和。

; 目的:学习简单的关于分支与数组处理的算法。 ; 算法描述 ; 1. esum=0;

; 2. for i=0 to n-1 do

; if a[i] is evennunber then esum=esum+a[i]; ; 判断偶数,采用 test 指令测试最低位。

; 合理分配寄存器:采用loop循环,ecx=lengthof array

; esum=eax=0,esi=0,做下标,采用带比例因子的相对寻址处理数组。 .686

.model flat,stdcall

option casemap:none includelib msvcrt.lib

printf PROTO C : dword,:vararg .data

array dword 12,34,123,78,43,234,79,86,98,20 esum dword ? fmtStr byte ' esum=%d',13,10,0 ;格式描述串 .code

main proc

mov ecx,lengthof array

xor eax,eax ;esum=eax=0 mov esi,eax ;数组下标 again: mov ebx,array[esi*4] test ebx,1 jnz next ;if a[i] is evennunber then esum=esum+a[i]; add eax,ebx ;注意:转换成汇编语言时,测试的是不是偶数时则取下一个数测试。 next: inc esi loop again

mov esum,eax invoke printf,offset fmtStr,esum ret ;return to Windows main endp ;end of main end main ;end of assembly 8.; Win32 Console Application ; 测试一字符串是否是“回文”, 是“回文”则显示“Y”,否则显示“N”。 ; 算法描述:

; left,right分别指向串的第一个和最后一个元素,采用首尾比较。 ; 1. left=0,right=n-1 ,flag='Y' ; ; 2. while left

; if a[left++]<>a[right--] then ; { flag= 'N'; break;} ; 3. printf flag

; 合理分配寄存器:left=esi,right=edi ,flag=al='Y' ; 采用相对寻址处理数组。 include io32.inc .data

msg byte 'level',0 count equ lengthof msg .code

main proc

mov esi,0 ;left指针

mov edi,count-2 ;right指针,串长不包括结束标志0 mov al,'Y' ; flag=al='Y'

.while (esi

next: inc esi ;移动指针指向下一个元素 dec edi ;移动指针指向下一个元素 .endw

display: call dispc call dispcrlf ret ;return to Windows main endp ;end of main end main ;end of assembly 9 .include io32.inc .data

blank byte ' ',0 char byte ?

anykey byte 13,10,'press any key to continue...',0 .code main proc mov ecx,10 mov ebx,ecx .repeat xor esi,esi mov eax,ecx .while(eax>0) xor edx,edx div ebx imul esi,10

add esi,edx .endw

cmp esi,ecx jne next mov eax,ecx call dispuid call dispcrlf next: inc ecx

.until(ecx>10000) ret

main endp end main

10.; Win32 Console Application ; 求2~100之间的所有素数。

; 目的:学习如何利用条件转移指令构造条件循环结构,多重循环的构造方法。 ; 学习子程序的构造与通过堆栈传递参数的方法。 ; 采用伪代码pseudo code描述算法 ; 1. i=2 to 100 do

; 1.1 if prime(i) then print i ; 构造函数prime(i):

; if i is prime number then prime(i)=1 else prime(i)=0

; 合理分配寄存器,i=ebx,j=ecx,edxeax做被除数,ecx做除数. include io32.inc .data msg byte ' List of prime number',13,10,0 msg1 byte ' pcounter is :' ,13,10,0 blank byte ' ',0

anyKey byte 13,10,'press any key to continue ...',13,10,0 parray dword 100 dup(?) pcounter dword 0 .code

main proc ;主程序开始 mov esi,0 mov eax,offset msg call dispmsg mov ebx,2 ;i循环的初值 .while (ebx<=100) ;i循环入口 push ebx ;push parameter on stack参数进栈 call prime test eax,eax jz next l1: mov parray[esi*4],ebx inc esi

mov eax,ebx call dispuid ;输出,用于验证。可以删掉 mov eax,offset blank call dispmsg next: inc ebx .endw

call dispcrlf mov eax,offset msg1 call dispmsg mov pcounter,esi mov eax,esi call dispuid call dispcrlf ret ;返回操作系统

main endp ;主程序结束 ;----------------------------------------------------- ; function: 判断一个无符号整数i是否是素数 ; Receives: 从栈获取无符号整数i

; Returns: if i is prime number then eax=1 else eax=0 ; 采用伪代码pseudo code描述算法 ; 1 j=2 to i/2 do

; 1.1 if i mod j=0 then {eax=0 return} ; 2 eax=1;return

; 合理分配寄存器,j=ecx,edxeax做被除数,ecx做除数. ;----------------------------------------------------- prime proc push ebp ;save ebp mov ebp,esp push ecx push edx push edi push esi ;save ,ecx,edx,edi,esi mov esi,[ebp+8] ;get parameter i mov edi,esi shr esi,1 ;esi=i/2 mov ecx,2 ;j循环入口 .while (ecx<=esi) mov eax,edi xor edx,edx ;edx=0 div ecx ;被除数送eax,32位除法 or edx,edx ;cmp edx,0 jz retZero ;if i mod j=0 then eax=0 inc ecx .endw

mov eax,1 ;i是否是素数eax=1 jmp restoreReg retZero: mov eax,0 restoreReg: pop esi pop edi pop edx pop ecx pop ebp ret 1*4 ;clean up stack prime endp end main ;end of assembly 11.; Win32 Console Application

; 利用子程序求3个无符号整数的最大公约数。 ; 目的:学习子程序的构造与参数的传递方法。 .686

.model flat,stdcall

option casemap:none includelib msvcrt.lib

printf PROTO C : dword,:vararg .data

dvar1 dword 2012 dvar2 dword 128 dvar3 dword 456

dgcd dword ? ;存放2个无符号整数的最大公约数 fmtStr byte ' gcd(%d,%d,%d)=%d',13,10,0 .code

main proc push dvar1

push dvar2 ;参数dvar1,dvar2进栈,传值 push offset dgcd ;dgcd的地址进栈,传地址

call Gcd ;dgcd=dvar1,dvar2的最大公约数 push dvar3

push dgcd ;参数dvar3,dgcd进栈,传值 push offset dgcd ;dgcd的地址进栈,传地址 call Gcd

invoke printf,offset fmtStr,dvar1,dvar2,dvar3,dgcd ret ;return to Windows main endp ;end of main Gcd proc

; function: 求2个无符号整数的最大公约数。 ; Receives: 从栈中获取无符号整数a,b及

; 存放最大公约数变量gcd的地址 ; Returns: gcd=无符号整数a,b的最大公约数。

; 注意:[ebp+8]是最后一个压入栈中的参数! ; 以[ebp+8]为基准,从栈中获取其它的参数。 ; 算法思想:采用欧几里得算法。gcd(a,0)=a; ; gcd(a,b)=gcd(b,a mod b) ; 算法描述:

; 1. while b<>0 do

; { r=a mod b;a=b;b=r;} ; 2. gcd=a;

; 注意合理的分配使用寄存器,edx,eax做被除数 ; ebx=gcd的地址,eax=a,ecx=b push ebp

mov ebp,esp ; 建立访问栈参数的指针基准 push eax ; 保护子程序中要使用的寄存器 push ebx push ecx push edx

mov ebx,[ebp+8] ;ebx=变量gcd的地址 mov ecx,[ebp+12] ;ecx=b mov eax,[ebp+16] ;eax=a .while (ecx!=0)

xor edx,edx ;被除数送edx,eax,32位除法 div ecx ;div指令执行后eax=商,edx=余数 mov eax,ecx ;a=b

mov ecx,edx ;b=r,edx=余数 .endw

mov [ebx],eax ;gcd=最大公约数

restore: pop edx ; 恢复子程序中使用过的寄存器 pop ecx pop ebx pop eax pop ebp

ret 3*4 ;清理栈中的参数 Gcd endp ;end of Gcd end main ;end of assembly 12. include io32.inc .data

string byte 'If you find any error in the program, you can DEBUG it.' count = sizeof string bug byte 'BUG' .code start:

mov ecx,count

mov edi,offset string L1: mov esi,offset bug

push edi

mov edx,sizeof bug LN: mov al,[esi] cmp [edi],al jne L2 inc esi inc edi dec edx jne LN pop edi mov al,'Y' jmp L3 L2: pop edi inc edi loop L1 mov al,'N' L3: call dispc exit 0 end start

13. include io32.inc .data

; 数据段

string byte 'Let us have a try !',0dh,0ah,0 .code start:

; 代码段

mov ecx,sizeof string cmp ecx,2 jb done

lea eax,string ; 显示处理前的字符串 call dispmsg mov esi,ecx dec esi

outlp: cmp string[esi],' ' ; 检测是否是空格 jnz next ; 不是空格继续循环

mov edi,esi ; 是空格,进入剔除空格分支 dec ecx inlp: inc edi

mov al,string[edi] ; 前移一个位置 mov string[edi-1],al cmp edi,ecx jb inlp

next: dec esi ; 继续进行 cmp esi,0

jnz outlp ; 为0结束

lea eax,string ; 显示处理后的字符串 call dispmsg done: exit 0 end start

14.include io32.inc .data

wvar dword 307281AFH .code start:

push wvar call disp add esp,4 mov al,'H' call dispc

; 代码段,子程序 disp proc push ebp mov ebp,esp push ebx push ecx mov ecx,8

mov eax,[ebp+8] dhw1: rol eax,4 mov ebx,eax

and al,0fh ; 转换为ASCII码 add al,30h cmp al,'9' jbe dhw2 add al,7

dhw2: call dispc mov eax,ebx loop dhw1 pop ecx pop ebx pop ebp ret

disp endp exit 0 end start

15.; Win32 Console Application ; 冒泡排序子程序。

; 目的:学习子程序的构造与参数的传递方法。

;================================================================= .686

.model flat,stdcall

option casemap:none ;case sensitive 大小写敏感 includelib msvcrt.lib ; C Run-Time Libraries (CRT) printf PROTO C : dword,:vararg scanf PROTO C : dword,:vararg

;================================================================= .data

array dword 12,4,168,122,-33,56,78,99,345,66,-5 count equ lengthof array fmtStr byte ']' .code

main proc

push offset array ;array的首地址进栈,传地址 push count ;数组元素的个数进栈,传值 call Bubble

xor esi,esi ;以下的while循环用于验证。可以删掉 .while (esi

invoke printf,offset fmtStr,array[esi*4] popad inc esi .endw ret ;return to Windows main endp ;end of main Bubble proc

; function: Bubble Sort

; Receives: 从栈获取数组的首地址及元素的个数 ; Returns: 无

; 注意:[ebp+8]是最后一个压入栈中的参数! ; 以[ebp+8]为基准,从栈中获取其它的参数。 ; Bubble Sort的思想:从第一个元素开始,

; 相邻的两个元素依次进行比较,若关系不对则交换。 ; 这样较小的数就向上移动,而较大的数则向下移动, ; 这就是冒泡排序的由来。经过N-1次比较, ; 最大的数被移动到最后一个位置, ; 这个过程称之为一趟扫描。

; 显然,经过N-1趟扫描,排序过程就结束了; ; 并且每趟扫描的比较次数比前一趟减少一次。 ; 算法描述:

; 1. ecx=n-1; ; 2. while ecx>0

; { esi=array;数组的首地址 ; ebx=ecx; ; while ebx>0

; { if [esi]>[esi+4] then ; swap [esi],[esi+4] ; ; esi=esi+4;ebx--; ; } ; ecx--;} push ebp

mov ebp,esp ; 建立访问栈参数的指针基准 push eax ; 保护子程序中要使用的寄存器 push ebx push ecx push esi push edi

mov esi,[ebp+12] ;array的首地址 mov edi,esi

mov ecx,[ebp+8] ;数组元素的个数 dec ecx again: mov esi,edi ;esi=array的首地址 mov ebx,ecx .while (ebx>0)

mov eax,[esi]

cmp eax,[esi+4] ; 比较两个相邻的元素 jl next

xchg eax,[esi+4]

mov [esi],eax ; 交换两个相邻的元素 next: add esi,4 ; esi指向下一个元素 dec ebx .endw

loop again

restore: popedi ; 恢复子程序中使用过的寄存器 pop esi pop ecx pop ebx pop eax pop ebp

ret 2*4 ;清理栈中的参数 Bubble endp ;end of Bubble end main ;end of assembly

; 1. ecx=n-1; ; 2. while ecx>0

; { esi=array;数组的首地址 ; ebx=ecx; ; while ebx>0

; { if [esi]>[esi+4] then ; swap [esi],[esi+4] ; ; esi=esi+4;ebx--; ; } ; ecx--;} push ebp

mov ebp,esp ; 建立访问栈参数的指针基准 push eax ; 保护子程序中要使用的寄存器 push ebx push ecx push esi push edi

mov esi,[ebp+12] ;array的首地址 mov edi,esi

mov ecx,[ebp+8] ;数组元素的个数 dec ecx again: mov esi,edi ;esi=array的首地址 mov ebx,ecx .while (ebx>0)

mov eax,[esi]

cmp eax,[esi+4] ; 比较两个相邻的元素 jl next

xchg eax,[esi+4]

mov [esi],eax ; 交换两个相邻的元素 next: add esi,4 ; esi指向下一个元素 dec ebx .endw

loop again

restore: popedi ; 恢复子程序中使用过的寄存器 pop esi pop ecx pop ebx pop eax pop ebp

ret 2*4 ;清理栈中的参数 Bubble endp ;end of Bubble end main ;end of assembly

本文来源:https://www.bwwdw.com/article/ngdx.html

Top