我在用汇编语言查找数组的平均值、最小值和最大值时遇到了问题。我用 C++ 创建了一个简单的数组,并创建了一个 test.asm 文件来传递它。我算出了平均值,但现在我似乎无法算出最小值和最大值。
#include <iostream>
using namespace std;
extern "C"
int test(int*, int);
int main()
{
const int SIZE = 7;
int arr[SIZE] = { 1,2,3,4,5,6,7 };
int val = test(arr, SIZE);
cout << "The function test returned: " << val << endl;
return 0;
}
这是我的 test.asm,它将所有值相加并返回 4。
.686
.model flat
.code
_test PROC ;named _test because C automatically prepends an underscode, it is needed to interoperate
push ebp
mov ebp,esp ;stack pointer to ebp
mov ebx,[ebp+8] ; address of first array element
mov ecx,[ebp+12]
mov ebp,0
mov edx,0
mov eax,0
loopMe:
cmp ebp,ecx
je allDone
add eax,[ebx+edx]
add edx,4
add ebp,1
jmp loopMe
allDone:
mov edx,0
div ecx
pop ebp
ret
_test ENDP
END
我仍在尝试找出如何找到最小值,因为最大值将以类似的方式完成。我假设您使用 cmp 来比较值,但到目前为止我尝试的一切都没有成功。我对汇编语言还很陌生,我很难掌握。感谢您的帮助。
最佳答案
Any help is appreciated
好的,我将向您展示重构的平均函数,即使您没有直接要求它。 :)
你可以从中学到的东西:
- 简化函数序言/结尾,当
ebp
未在代码中修改时 - 输入数组包含 32b 个
int
值,因此要获得正确的平均值,您应该计算 64b 和,并进行 64b 和有符号除法 - 巧妙“技巧”如何获得零值 (
xor
) 或inc
如何对值 +1(降低代码大小) - 通过返回伪造的平均值
0
处理大小为零的数组(没有崩溃) - 添加由 32b 寄存器/指令组成的两个 64b 值
- 计算人类“索引”(+1 => 可能使用
size
直接 cmp),但寻址 32b 值(在寻址中使用*4
) - 重命名为
getAverage
顺便说一句,这并没有针对性能进行优化,我试图使源代码保持“简单”,因此很容易阅读和理解它在做什么。
_getAverage PROC
; avoiding `ebp` usage, so no need to save/set it
mov ebx,[esp+4] ; address of first array element
mov ecx,[esp+8] ; size of array
xor esi,esi ; array index 0
; 64b sum (edx:eax) = 0
xor eax,eax
cdq
; test for invalid input (zero sized array)
jecxz zeroSizeArray ; arguments validation, returns 0 for 0 size
; here "0 < size", so no "index < size" test needed for first element
; "do { ... } while(index < size);" loop variant
sumLoop:
; extend value from array[esi] to 64b (edi is upper 32b)
mov edi,[ebx+esi*4]
sar edi,31
; edx:eax += edi:array[esi] (64b array value added to 64b sum)
add eax,[ebx+esi*4]
adc edx,edi
; next index and loop while index < size
inc esi
cmp esi,ecx
jb sumLoop
; divide the 64b sum of integers by "size" to get average value
idiv ecx ; signed (!) division (input array is signed "int")
; can't overflow (Divide-error), as the sum value was accumulated
; from 32b values only, so EAX contains full correct result
zeroSizeArray:
ret
_getAverage ENDP
关于c++ - 在 assembly 中找到平均值、最小值和最大值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40253962/