汇编语言系列文章仅作为实验报告和汇编学习参考,不作为任何技术文章,还望大佬们勿喷。
1. 实验名称
熟悉汇编语言的基本指令和条件指令的使用,理解汇编程序中,如何实现高级语言中的条件语句。
2. 实验要求
编写整数求和程序;运用kip irvine库中的部分过程,并阅读分析其实现源码。
3. 实验内容
- 编写多个整数求和的程序:对用户输入的多个整数进行求和,并输出结果。
阅读然后修改附录A中的求和程序(该程序实现了3个整个求和的功能),使用一个常量决定数组的大小(即程序最大可以求和的整数个数):
ARRAY_SIZE = 20
Array DWORD ARRAY_SIZE DUP(?)
写一个过程提示用户输入需要求和的整数的个数,向promptForIntegers过程传递用户输入的数值。如果用户的输入值大于ARRAY_SIZE(判断的示例代码参见附录B),那么显示一条错误信息并退出程序。提示和错误信息可以如下例所示:
How many integers will be added? 21
The array cannot be larger than 20
精心设计程序,使得在修改了ARRAY_SIZE后,错误提示信息中的ARRAY_SIZE数目值(在上例中是20)也应自动修改。
提示:
a). 编程能力一般的同学可以分两步:- 弄懂附录A的程序。该程序实现了3个整个求和的功能。
- 找到附录A的程序需要修改的地方,以实现多个整数求和。
b). 编程能力较强的同学建议直接编写程序实现。
- 对上述程序添加功能:除显示多个整数的和外,还分别显示这些整数中正整数的和负整数的和。(区分正数与负数的示例代码参见附录B)
- (可选)阅读kip irvine库中的部分过程的源码
Irvine 32位库的源码在文件Irvine32.asm中(在Irvine32_Library_sourceCode.rar压缩包中)。
建议阅读源码的过程是:DumpMem,DumpRegs,IsDigit,Random32,RandomRange,ReadChar。
4. 实验步骤或源代码、结果
1. 实验步骤
- 编写多个整数求和的程序:对用户输入的多个整数进行求和,并输出结果。
当输入的数字个数不大于20时可以进行多个整数求和,并正确输出结果。

当输入的数字个数大于20时不可以进行多个整数求和,输出错误信息。
mov edx, OFFSET str4 ; "The array cannot be larger than "call WriteStringmov eax, ARRAY_SIZEcall WriteInt ; 输出最大值
错误提示信息中的ARRAY_SIZE数目值也应自动修改。
- 对上述程序添加功能:除显示多个整数的和外,还分别显示这些整数中正整数的和负整数的和。


2. 实验源代码、结果
1. 源代码1
INCLUDE Irvine32.incARRAY_SIZE = 20.datastr1 BYTE "How many integers will be added? ", 0str2 BYTE "Enter a signed integer: ", 0str3 BYTE "The sum of the integer is: ", 0str4 BYTE "The array cannot be larger than ", 0str5 BYTE "The array cannot be less than 0 ", 0array DWORD ARRAY_SIZE DUP(?)TheArraySize SDWORD ?.codemain PROCcall Clrscrmov esi,OFFSET arraycall GetArraySizecmp TheArraySize, ARRAY_SIZEjg GreaterErrorcmp TheArraySize, 0jng Less0Errormov ecx, TheArraySizecall PromptForIntegerscall ArraySumcall DisplaySumjmp ExitProcGreaterError:mov edx, OFFSET str4 ; "The array cannot be larger than "call WriteStringmov eax, ARRAY_SIZEcall WriteInt ; 输出最大值call Crlfjmp ExitProcLess0Error:mov edx, OFFSET str5 ; "The array cannot be less than 0."call WriteStringcall Crlfjmp ExitProcExitProc:exitmain ENDPGetArraySize PROC USES eax edxmov edx, OFFSET str1call WriteStringcall ReadIntcall Crlfmov TheArraySize, eaxretGetArraySize ENDP;----------------------------------------------------PromptForIntegers PROC USES ecx edx esi;; Prompts the user for an arbitrary number of integers; and inserts the integers into an array.; Receive ESI points to the array, ECX = array size; Returns: nothing;-----------------------------------------------------------mov edx, OFFSET str2 ; "Enter a signed integer"L1: call WriteString ; display a stringcall ReadInt ; readcall Crlf ; go to next output linemov [esi], eax ; store in arrayadd esi, TYPE DWORD ; next integerloop L1retPromptForIntegers ENDP;----------------------------------------------------------ArraySum PROC USES esi ecx;; Calculates the sum of an array of 32-bit integers.; Receives: ESI points to the array, ECX = number; of array elements; Returns: EAX = sum of the array elements;------------------------------------------------------------mov eax, 0L1:add eax, [esi]add esi, TYPE DWORD ; point to next integerloop L1 ; repeat for array sizeret ; sum is in EAXArraySum ENDP;-------------------------------------------------------------DisplaySum PROC USES edx;; Displays the sum on the screen; Receives: EAX = the sum; Return: nothing;-------------------------------------------------------------mov edx, OFFSET str3 ;"The sum of the .."call WriteStringcall WriteInt ;display EAXcall CrlfretDisplaySum ENDPEND main
2. 源代码2
INCLUDE Irvine32.incARRAY_SIZE = 20.datastr1 BYTE "How many integers will be added? ", 0str2 BYTE "Enter a signed integer: ", 0str3 BYTE "The sum of the integer is: ", 0str4 BYTE "The array cannot be larger than ", 0str5 BYTE "The array cannot be less than 0 ", 0str6 BYTE "The sum of the positive integer is: ", 0str7 BYTE "The sum of the negative integer is: ", 0array DWORD ARRAY_SIZE DUP(?)TheArraySize SDWORD ?.codemain PROCcall Clrscrmov esi,OFFSET arraycall GetArraySizecmp TheArraySize, ARRAY_SIZEjg GreaterErrorcmp TheArraySize, 0jng Less0Errormov ecx, TheArraySizecall PromptForIntegerscall ArraySumcall DisplaySumjmp ExitProcGreaterError:mov edx, OFFSET str4 ; "The array cannot be larger than "call WriteStringmov eax, ARRAY_SIZEcall WriteInt ; 输出最大值call Crlfjmp ExitProcLess0Error:mov edx, OFFSET str5 ; "The array cannot be less than 0."call WriteStringcall Crlfjmp ExitProcExitProc:exitmain ENDPGetArraySize PROC USES eax edxmov edx, OFFSET str1call WriteStringcall ReadIntcall Crlfmov TheArraySize, eaxretGetArraySize ENDP;----------------------------------------------------PromptForIntegers PROC USES ecx edx esi;; Prompts the user for an arbitrary number of integers; and inserts the integers into an array.; Receive ESI points to the array, ECX = array size; Returns: nothing;-----------------------------------------------------------mov edx, OFFSET str2 ; "Enter a signed integer"L1: call WriteString ; display a stringcall ReadInt ; readcall Crlf ; go to next output linemov [esi], eax ; store in arrayadd esi, TYPE DWORD ; next integerloop L1retPromptForIntegers ENDP;----------------------------------------------------------ArraySum PROC USES esi ecx;; Calculates the sum of an array of 32-bit integers.; Receives: ESI points to the array, ECX = number; of array elements; Returns: EAX = sum of the array elements;------------------------------------------------------------mov eax, 0mov ebx, 0mov edx, 0L1: cmp [esi], edxjnl positive_zeroadd ebx, [esi]jmp loopL1positive_zero:add eax, [esi]jmp loopL1loopL1:add esi, TYPE DWORD ; point to next integerloop L1 ; repeat for array sizeret ; sum is in EAXArraySum ENDP;-------------------------------------------------------------DisplaySum PROC USES edx ecx;; Displays the sum on the screen; Receives: EAX = the sum; Return: nothing;-------------------------------------------------------------mov ecx, eaxadd eax, ebxmov edx, OFFSET str3 ;"The sum of the .."call WriteStringcall WriteInt ;display EAXcall Crlfmov edx, OFFSET str6 ;"The sum of the positive integers"mov eax, ecxcall WriteStringcall WriteInt ;display EAXcall Crlfmov edx, OFFSET str7 ;"The sum of the negative integers"mov eax, ebxcall WriteStringcall WriteInt ;display EAXcall CrlfretDisplaySum ENDPEND main
5. 实验结论和心得体会
- 学会了多整数求和的汇编代码;
- 学会了2个数比较大小的汇编代码,要注意有符号比较和无符号比较;
- 在实验中遇到了随机性的问题,发现是使用了被保护的eax,导致错误,将eax的值赋给一个常量后用常量去比较;
- 对于几个寄存器的用法要牢记,多写程序就可以熟练;
- 调用ReadInt时会默认读取eax寄存器的值;
- 在分别求正整数和以及负整数和时,先将数字和0比较,然后分别加到两个寄存器中,最后再将2个寄存器的值加起来就是总的和。
