Arrays 求数组中的间隙之和,汇编语言
我在这个问题上被困得发疯。我们应该找到数组中的间隙之和。我已经编写了查找数组和的代码,但不知道如何查找间隙和。这是我的。所以差距是2,3,4,1,总和应该是10Arrays 求数组中的间隙之和,汇编语言,arrays,assembly,Arrays,Assembly,我在这个问题上被困得发疯。我们应该找到数组中的间隙之和。我已经编写了查找数组和的代码,但不知道如何查找间隙和。这是我的。所以差距是2,3,4,1,总和应该是10 .386 .model flat,stdcall .stack 4096 ExitProcess proto,dwExitCode:dword .data array DWORD 0,2,5,9,10 .code main proc mov edi,OFFSET array mov ecx,LENGTHOF
.386
.model flat,stdcall
.stack 4096
ExitProcess proto,dwExitCode:dword
.data
array DWORD 0,2,5,9,10
.code
main proc
mov edi,OFFSET array
mov ecx,LENGTHOF array
mov eax,0
L1:
add eax,[edi]
add edi,TYPE array
loop L1
invoke ExitProcess,0
main endp
end main
我不想刷新我的程序集。。。但是为了让您开始学习,下面是我如何在C语言中实现这一点(它被称为高级PDP-11汇编程序IIRC)
int数组[5]=[0,2,5,9,10]
整数和=0;
整数长度=5;
对于(i=0;i
找到差距总和的漫长道路:
.386
.model flat,stdcall
.stack 4096
ExitProcess proto,dwExitCode:dword
.data
array DWORD 0,2,5,9,10
.code
main proc
mov esi,OFFSET array
mov ecx,LENGTHOF array
mov ebx,0 ; Start sum at 0
cld ; Clear the direction bit (look up the LODS instruction!)
lodsd ; Get the first value to start
mov edx, eax ; Save "previous" element read in edx
dec ecx ; Decrement the loop counter 'cuz we read one
L1:
lodsd
sub ebx, edx ; sum = sum + (this element - prev element)
add ebx, eax ; or, sum = sum - prev, then sum = sum + this
mov edx, eax ; save previous element in edx
loop L1
mov eax, ebx ; put the result in eax
invoke ExitProcess,0
main endp
end main
如果您需要长期使用,但不允许使用lodsd
,那么我将其作为一个练习,将您的循环转换为不使用lodsd
简单的方法是认识到差距的总和是:
(a[1] - a[0]) + (a[2] - a[1]) + ... + (a[N] - a[N-1])
假设不取差值的绝对值,它只是:a[N]-a[0]
。可以按如下方式计算(注意:我不确定这里的array+offset的MASM语法,因此您可能需要修改一下):
那样有帮助,我会继续努力的。很抱歉格式不好,我仍然在学习这个站点代码块。从技术上讲,你可以把它放在一个c程序中(带一个主包装器),然后使用gcc-S(我想,也许是-S)来生成程序集。我强烈反对直接使用它,因为如果您刚开始使用assembly,那么它可能使用的指令(特别是在高度优化的情况下)可能会非常古怪。是的,我刚开始使用assembly。问题是我们的课文很糟糕,全班同学都讨厌它的布局,还有一些非常糟糕的例子。我在为每一项任务而挣扎。我已经比较了VB、java和C++以及汇编臭味。我仍然无法实现这一点:/您可以从位置
数组+4*4
读取dword
(这是基数加上dword
(4)乘以元素索引,其中第一个索引为0)。然后减去从locationarray
读取的dword
。错误:您编写了array[0]
,而不是array[i]
。通过减去两个值可以得到一个间隙。你的循环应该比项目数少一个,因为间隔比项目数少一个。刚刚看到你的回复,仍然在使用该站点。我不知道如何缩短循环。它不是像mov ecx,LENGTHOF array/1吗?间隙的总和只是最后一个元素减去第一个元素,除非你说的是间隙的绝对值,在这种情况下,如果数字不增加,就不会是这样。在这种情况下,总和应该是10,间隙是书中给出的2,3,4,1。对。这与最后一个元素10减去第一个元素0相同。我要说的是,要计算间隙之和,你只需要从最后一个元素中减去第一个元素。这是因为间隙之和是(a1-a0)+(a2-a1)+…+(AN-AN-1)和中间的所有项都取消,留给您<代码> -A0。tbh我更喜欢第一个例子,但我检查了一下,lodsd在我们的课堂上还有几周没有涉及,所以我不知道它是否会被接受。它没有说绝对值,所以我认为这无关紧要。感谢您的帮助,以及解释“做什么”的评论。汇编要比C++更多的时间来理解。我想,如果你必须这样做,你可以把第一个例子转换成离散的地址。查看lodsd
的功能,然后模仿它。它所做的只是(1)将esi
指向的内容移动到eax
,然后(2)将esi
增加eax
字节的大小(即4)。很简单。谷歌搜索“MASM寻址模式”,如果需要的话。我继续向前看,在我们的文本中找到了losds的功能。它基本上说它将esi中的任何内容加载到eax中,所以在我看来,我所要做的就是将lodsd更改为mov eax,但esi不起作用/@megagig由于数组中的第一个值是0
,并且您可能已经在eax
中有0
,因此它在没有第一个lodsd
的情况下正常工作。但正确的解决方案会保留第一个lodsd
。记住,如果一个程序碰巧工作,它不一定是正确的。:)理解的真正关键是努力了解为什么每一步都有。删除某些内容以查看其是否仍然有效可能是非常具有欺骗性的。第一个版本有一个超出必要的循环承载依赖链sum+=a[i+1]
/sum-=a[i]
修改sum
两次,因此循环受延迟限制,每2次迭代运行一个周期。如果您保持足够低的循环开销,那么执行sum+=(a[i+1]-a[i])
可以每1次迭代运行一个循环。但是,在寄存器中保留“next”元素作为下一次迭代的“prev”元素很好。您测试过这个吗?两个元素之间的差距只取决于这些元素,而不取决于差距的旧值,如果你阅读现有的答案,你会注意到这一点。如果你认为你有一些有用的东西可以添加一个新的答案,你应该用代码外的文本来解释代码的有趣之处。感谢你的专注,我测试了这段代码。这段代码生成了两个单独值之间的所有差值之和。例如,如果我们有一个数组0,3,5,那么前两个元素之间的差值是3,但是你添加了eax,[esi+4]
而不是mov-eax,[esi+4]
。因此,在第二次迭代中,您将在0,3,5示例中执行sum+=5
,而不是sum+=2
。这就是我所说的不依赖于差距的旧值的意思。再次感谢,让我们重新考虑一下这个例子
(a[1] - a[0]) + (a[2] - a[1]) + ... + (a[N] - a[N-1])
.386
.model flat,stdcall
.stack 4096
ExitProcess proto,dwExitCode:dword
.data
array DWORD 0,2,5,9,10
.code
main proc
mov ebx, LENGTHOF array
dec ebx ; last element is at length-1 index
shl ebx, 2 ; length * 4 for size of DWORD
mov eax, [array + ebx] ; read last element
sub eax, [array] ; subtract first element
invoke ExitProcess,0
main endp
end main
Include Irvine32.inc
.data
array dword 0,2,5,7,9] ; Array initializatiom
Sum dword 0 ; variable containing sum
counter dword ?
.code
main proc
mov eax,0 ; eax=0 because no garbage value is shown
mov esi,offset array ; esi caontain array 1st index address
mov ecx,lengthof array-1 ; loop is repeated 4 times as two no are compared
l1:
add eax,[esi+4] ; eax have 2nd value of array
sub eax,[esi] ; sub array 2nd and first value
add esi,type array ; Esi have next array value after each alteration
add sum,eax ; Sum is stored after each alteration
loop l1
call writeint
exit
main ENDP
END main