【汇编语言实验二】多整数求和程序的编写

1. 实验名称

熟悉汇编语言的基本指令和条件指令的使用,理解汇编程序中,如何实现高级语言中的条件语句。

2. 实验要求

编写整数求和程序;运用kip irvine库中的部分过程,并阅读分析其实现源码。

3. 实验内容

  1. 编写多个整数求和的程序:对用户输入的多个整数进行求和,并输出结果。
    阅读然后修改附录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). 编程能力较强的同学建议直接编写程序实现。
  2. 对上述程序添加功能:除显示多个整数的和外,还分别显示这些整数中正整数的和负整数的和。(区分正数与负数的示例代码参见附录B)
  3. (可选)阅读kip irvine库中的部分过程的源码
    Irvine 32位库的源码在文件Irvine32.asm中(在Irvine32_Library_sourceCode.rar压缩包中)。
    建议阅读源码的过程是:DumpMem,DumpRegs,IsDigit,Random32,RandomRange,ReadChar。

4. 实验步骤或源代码、结果

1. 实验步骤

  1. 编写多个整数求和的程序:对用户输入的多个整数进行求和,并输出结果。
    当输入的数字个数不大于20时可以进行多个整数求和,并正确输出结果。

1

当输入的数字个数大于20时不可以进行多个整数求和,输出错误信息。
mov edx, OFFSET str4 ; "The array cannot be larger than "
call WriteString
mov eax, ARRAY_SIZE
call WriteInt ; 输出最大值
错误提示信息中的ARRAY_SIZE数目值也应自动修改。

2

  1. 对上述程序添加功能:除显示多个整数的和外,还分别显示这些整数中正整数的和负整数的和。

3

4

2. 实验源代码、结果

  1. 源代码
INCLUDE Irvine32.inc
ARRAY_SIZE = 20

.data
str1 BYTE "How many integers will be added? ", 0
str2 BYTE "Enter a signed integer: ", 0
str3 BYTE "The sum of the integer is: ", 0
str4 BYTE "The array cannot be larger than ", 0
str5 BYTE "The array cannot be less than 0 ", 0
array DWORD ARRAY_SIZE DUP(?)
TheArraySize SDWORD ?

.code
main PROC
	call Clrscr
	mov esi,OFFSET array
	call GetArraySize
	cmp TheArraySize, ARRAY_SIZE
	jg GreaterError
	cmp TheArraySize, 0
	jng Less0Error
	mov ecx, TheArraySize
	call PromptForIntegers
	call ArraySum
	call DisplaySum
	jmp ExitProc
GreaterError:
	mov edx, OFFSET str4	; "The array cannot be larger than "
	call WriteString
	mov eax, ARRAY_SIZE
	call WriteInt	; 输出最大值
	call Crlf
	jmp ExitProc
Less0Error:
	mov edx, OFFSET str5	; "The array cannot be less than 0."
	call WriteString
	call Crlf
	jmp ExitProc
ExitProc:
	exit
main ENDP

GetArraySize PROC USES eax edx
	mov edx, OFFSET str1
	call WriteString
	call ReadInt
	call Crlf
	mov TheArraySize, eax
	ret
GetArraySize 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 string
	call ReadInt	; read
	call Crlf	; go to next output line
	mov [esi], eax	; store in array
	add esi, TYPE DWORD	; next integer
	loop L1
	ret
PromptForIntegers 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, 0
L1: 
	add eax, [esi]
	add esi, TYPE DWORD	; point to next integer
	loop L1	; repeat for array size
	ret	; sum is in EAX
ArraySum 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 WriteString
	call WriteInt	;display EAX
	call Crlf
	ret
DisplaySum ENDP
END main
  1. 源代码
INCLUDE Irvine32.inc
ARRAY_SIZE = 20

.data
str1 BYTE "How many integers will be added? ", 0
str2 BYTE "Enter a signed integer: ", 0
str3 BYTE "The sum of the integer is: ", 0
str4 BYTE "The array cannot be larger than ", 0
str5 BYTE "The array cannot be less than 0 ", 0
str6 BYTE "The sum of the positive integer is: ", 0
str7 BYTE "The sum of the negative integer is: ", 0
array DWORD ARRAY_SIZE DUP(?)
TheArraySize SDWORD ?

.code
main PROC
	call Clrscr
	mov esi,OFFSET array
	call GetArraySize
	cmp TheArraySize, ARRAY_SIZE
	jg GreaterError
	cmp TheArraySize, 0
	jng Less0Error
	mov ecx, TheArraySize
	call PromptForIntegers
	call ArraySum
	call DisplaySum
	jmp ExitProc
GreaterError:
	mov edx, OFFSET str4	; "The array cannot be larger than "
	call WriteString
	mov eax, ARRAY_SIZE
	call WriteInt	; 输出最大值
	call Crlf
	jmp ExitProc
Less0Error:
	mov edx, OFFSET str5	; "The array cannot be less than 0."
	call WriteString
	call Crlf
	jmp ExitProc
ExitProc:
	exit
main ENDP

GetArraySize PROC USES eax edx
	mov edx, OFFSET str1
	call WriteString
	call ReadInt
	call Crlf
	mov TheArraySize, eax
	ret
GetArraySize 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 string
	call ReadInt	; read
	call Crlf	; go to next output line
	mov [esi], eax	; store in array
	add esi, TYPE DWORD	; next integer
	loop L1
	ret
PromptForIntegers 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, 0
	mov ebx, 0
	mov edx, 0
L1: cmp [esi], edx
	jnl	positive_zero
	add ebx, [esi]
	jmp loopL1
positive_zero:
	add eax, [esi]
	jmp loopL1
loopL1:
	add esi, TYPE DWORD	; point to next integer
	loop L1	; repeat for array size
	ret	; sum is in EAX
ArraySum ENDP

;-------------------------------------------------------------
DisplaySum PROC USES edx ecx
;
; Displays the sum on the screen
; Receives: EAX = the sum
; Return: nothing
;-------------------------------------------------------------
	mov ecx, eax
	add eax, ebx
	mov edx, OFFSET str3	;"The sum of the .."
	call WriteString
	call WriteInt	;display EAX
	call Crlf
	mov edx, OFFSET str6	;"The sum of the positive integers"
	mov eax, ecx
	call WriteString
	call WriteInt	;display EAX
	call Crlf
	mov edx, OFFSET str7	;"The sum of the negative integers"
	mov eax, ebx
	call WriteString
	call WriteInt	;display EAX
	call Crlf
	ret
DisplaySum ENDP
END main

5. 实验结论和心得体会

  • 学会了多整数求和的汇编代码;
  • 学会了2个数比较大小的汇编代码,要注意有符号比较和无符号比较;
  • 在实验中遇到了随机性的问题,发现是使用了被保护的eax,导致错误,将eax的值赋给一个常量后用常量去比较;
  • 对于几个寄存器的用法要牢记,多写程序就可以熟练;
  • 调用ReadInt时会默认读取eax寄存器的值;
  • 在分别求正整数和以及负整数和时,先将数字和0比较,然后分别加到两个寄存器中,最后再将2个寄存器的值加起来就是总的和。
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值