1:使用PROC伪指令定义参数方式不通过寄存器传参,计算数组之和
.386
.model flat,stdcall.stack 4096
ExitProcess PROTO,dwExitCode:DWORD.data
array DWORD 10000h,20000h,30000h,40000h,50000h
theSum DWORD ?.code
ArraySum PROC USES esi ecx,ptrArray:PTR DWORD,szArray:DWORDmov esi,ptrArraymov ecx,szArraymov eax,0cmp ecx,0je L2
L1:add eax,[esi]add esi,4loop L1
L2:ret
ArraySum ENDPmain PROCINVOKE ArraySum,ADDR array, ;数组地址LENGTHOF array;元素个数mov theSum,eax;保存和数INVOKE ExitProcess,0
main ENDP
END main
2:使用PROC伪指令定义参数方式不通过寄存器传参,交换两个值
include Irvine32.incSwap PROTO,pValx:PTR DWORD ,pValy:PTR DWORD
.data
Array DWORD 10000h,20000h.code
main PROC;显示交换前的数组mov esi,OFFSET Arraymov ecx ,2mov ebx,TYPE Arraycall DumpMemINVOKE Swap,ADDR Array,ADDR[Array + 4]call DumpMemexit
main ENDPSwap PROC USES eax esi edi,pValx:PTR DWORD,pValy:PTR DWORDmov esi,pValxmov edi,pValymov eax,[esi]xchg eax,[edi]mov [esi],eaxret
Swap ENDP
END main
3:EXTERNDEF_INCLUDE : EXTERNDEF和INCLUDE伪指令,跨模块使用变量和标号
vars.inc
EXTERNDEF count:DWORD , SYM1:ABS
sub1.asm
.386
.model flat,stdcall
include vars.incSYM1 = 10
.data
count DWORD 0
END
main.asm
.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO,dwExitCode:DWORDinclude vars.inc
.code
main PROCmov count,2000hmov eax,SYM1INVOKE ExitProcess,0
main ENDP
END main
4:EXTERN : 用EXTERN伪指令,多模块编写过程调用,传统的使用
ArraySum.asm
;ArraySum过程
include Irvine32.inc.code
;计算32位整数数组之和
;接收:
; ptrArray ;数组指针
; arraySize;数组大小(DWORD)
;返回:EAX = 和数
ArraySum PROCptrArray EQU [ebp+8]arraySize EQU [ebp+12]enter 0,0push ecx push esimov eax,0mov esi,ptrArraymov ecx,arraySizecmp ecx,0jle L2
L1:add eax,[esi]add esi,4loop L1
L2:pop esipop ecxleaveret 8
ArraySum ENDP
END
DisplaySum.asm
;DisplaySum
include Irvine32.inc.code
;在控制台显示和数
;接收:
; ptrPrompt ;提示字符串的偏移量
; theSum ;数组和数(DWORD)
;返回:无
DisplaySum PROCtheSum EQU [ebp+12]ptrPrompt EQU [ebp+8]enter 0,0push eaxpush edxmov edx,ptrPromptcall WriteStringmov eax,theSumcall WriteIntcall Crlfpop edxpop eaxleaveret 8
DisplaySum ENDP
END
PromptForIntegers.asm
;提示整数输入
include Irvine32.inc.code
;提示用户为数组输入整数,并用用户输入填充数组
;接收:
; ptrPrompt:PTR BYTE ;提示信息字符串
; ptrArray:PTR DWORD ;数组指针
; arraySize:DWORD ;数组大小
;返回:无
PromptForIntegers PROCarraySize EQU [ebp+16]ptrArray EQU [ebp+12]ptrPrompt EQU [ebp+8]enter 0,0pushad mov ecx,arraySizecmp ecx,0jle L2mov edx,ptrPromptmov esi,ptrArray
L1:call WriteStringcall ReadIntcall Crlfmov [esi],eaxadd esi,4loop L1
L2:popadleaveret 12
PromptForIntegers ENDP
END
Startup.asm
;整数求和过程
;多模块示例
;本程序由用户输入多个整数
;将它们存入数组,计算数组之和
;并显示和数
include Irvine32.incEXTERN PromptForIntegers@0:PROC
EXTERN ArraySum@0:PROC , DisplaySum@0:PROC;为了方便,重新定义外部符号
ArraySum EQU ArraySum@0
PromptForIntegers EQU PromptForIntegers@0
DisplaySum EQU DisplaySum@0
;修改Count来改变数组大小
Count = 3.data
prompt1 BYTE "Enter a signed integers: ",0
prompt2 BYTE "The sum of the integers is: ",0
array DWORD Count DUP(?)
sum DWORD ?.code
main PROCcall Clrscr;PromptForIntegers(addr prompt1,addr array,Count)push Countpush OFFSET arraypush OFFSET prompt1call PromptForIntegers;sum = ArraySum(addr array,Count)push Countpush OFFSET arraycall ArraySummov sum,eax;DisplaySum(addr prompt2,sum)push sumpush OFFSET prompt2call DisplaySumcall Crlfexit
main ENDP
END main
5:INVOKE_PROC_PROTO : 使用INVOKE和PROC和PROTO更高级的来进行多模块编程,相比EXTERN简化很多细节
arraySum.am
;ArraySum 过程
include sum.inc.code
ArraySum PROC,ptrArray:PTR DWORD, ;数组指针arraySize:DWORD ;数组大小
;计算32位整数数组之和
;返回:EAX = 和数push ecx push esimov eax,0mov esi,ptrArraymov ecx,arraySizecmp ecx,0jle L2
L1:add eax,[esi]add esi,4loop L1
L2:pop esipop ecxret
ArraySum ENDP
END
display.asm
;Display过程
include sum.inc.code
DisplaySum PROC,ptrPrompt:PTR BYTE, ;提示字符串theSum:DWORD ;数组之和
;
;在控制台显示和数
;返回:无push eaxpush edxmov edx,ptrPrompt call WriteStringmov eax,theSumcall WriteIntcall Crlfpop edxpop eaxret
DisplaySum ENDP
END
prompt.asm
;提示整数输入请求
include sum.inc ;获取过程.code
PromptForIntegers PROC,ptrPrompt:PTR BYTE, ;提示字符串ptrArray:PTR DWORD, ;数组指针arraySize:DWORD ;数组大小;提示用户输入数组幸免于难,并用用户输入填充数组;返回:无pushad mov ecx,arraySizecmp ecx,0jle L2mov edx,ptrPromptmov esi,ptrArray
L1:call WriteStringcall ReadIntcall Crlfmov [esi],eaxadd esi,4loop L1
L2:popadret
PromptForIntegers ENDP
END
sum.inc
include Irvine32.incPromptForIntegers PROTO,ptrPrompt:PTR BYTE , ;提示字符串ptrArray:PTR DWORD, ;数组指针arraySize:DWORD ;数组大小ArraySum PROTO,ptrArray:PTR DWORD, ;数组指针arraySize:DWORD ;数组大小DisplaySum PROTO,ptrPrompt:PTR BYTE, ;提示字符串theSum:DWORD ;数组之和
sum_main.asm
;整数求和
include sum.inc
Count = 3
.data
prompt1 BYTE "Enter a signed integers: ",0
prompt2 BYTE "The sum of the integers is: ",0
array DWORD Count DUP(?)
sum DWORD ?.code
main PROCcall ClrscrINVOKE PromptForIntegers,ADDR prompt1,ADDR array,CountINVOKE ArraySum,ADDR array,Countmov sum,eaxINVOKE DisplaySum,ADDR prompt2,sumcall Crlfexit
main ENDP
END main
6:使用LOCAL 定义一系列局部变量
.386
.model flat,stdcall.stack 4096
ExitProcess PROTO,dwExitCode:DWORD.code
main PROCcall Proc_1INVOKE ExitProcess,0
main ENDPProc_1 PROCLOCAL pArray:PTR DWORD,buffer[20]:BYTE,pwArray:WORD,myByte:SBYTE,myArray[20]:DWORDret
Proc_1 ENDPEND main
7:编写过程ShowParams,显示过程参数。显示被调用过程运行时堆栈中32位参数的地址和十六进制数值 过程接收一个参数,表示显示参数的个数
include Irvine32.inc.stack 4096
ExitProcess PROTO,dwExitCode:DWORD
MySample PROTO ,first:DWORD,second:DWORD,third:DWORD.data
outAddr BYTE "Address ",0
outEqule BYTE " = ",0 .code
main PROCINVOKE MySample,1234h,5000h,6543hINVOKE ExitProcess,0
main ENDPMySample PROC ,first:DWORD,second:DWORD,third:DWORDparamCount = 3push paramCount ;显示MySample中的三个参数call ShowParamsret
MySample ENDPShowParams PROC arg1 EQU [ebp+8]enter 0,0push ecxpush esipush edxmov ecx,arg1mov esi,[ebp]add esi,8
L1:mov edx,OFFSET outAddrcall WriteStringmov eax,esicall WriteHexmov edx,OFFSET outEqulecall WriteStringmov eax,[esi]call WriteHexcall Crlfadd esi,4loop L1pop edxpop esipop ecxleaveret 4
ShowParams ENDP
END main
8:MOVSB : (字节)从ESI的寻址的内存数据复制到EDI寻址的内存位置,加上rep 重复操作
.386
.model flat,stdcall.stack 4096
ExitProcess PROTO,dwExitCode:DWORD.data
string1 BYTE "ABCDEFGHIJKLMN",0
string2 BYTE "abcdefghijklmn",0.code
main PROCcld ;清除方向标志位mov esi,OFFSET string1 ;esi 指向源mov edi,OFFSET string2 ;edi 指向目的mov ecx,10 ;计数器为10rep movsb ;传送10个字节INVOKE ExitProcess,0
main ENDP
END main
9:MOVSD : (双字)从ESI的寻址的内存数据复制到EDI寻址的内存位置,加上rep 重复操作
.386
.model flat,stdcall.stack 4096
ExitProcess PROTO,dwExitCode:DWORD.data
source DWORD 20 DUP(0FFFFFFFFh)
target DWORD 20 DUP(?).code
main PROCcld ;清除方向标志位mov esi,OFFSET source ;esi 指向源mov edi,OFFSET target ;edi 指向目的mov ecx,LENGTHOF source ;计数器为10rep movsd ;传送10个字节INVOKE ExitProcess,0
main ENDP
END main
10:CMPSD : (双字)比较ESI指向的内存操作数与EDI指向的内存操作数
.386
.model flat,stdcall.stack 4096
ExitProcess PROTO,dwEixtCode:DWORD.data
source DWORD 1234h
target DWORD 5678h.code
main PROCmov esi, OFFSET sourcemov edi,OFFSET targetcldcmpsd ;比较双字ja L1 ;若source>target则跳转
L1:mov esi ,OFFSET sourcemov edi,OFFSET targetcldmov ecx , LENGTHOF source ;设置重复计数器repe cmpsd ;相等则重复INVOKE ExitProcess,0
main ENDP
END main