Arrays 求数组中的间隙之和,汇编语言

Arrays 求数组中的间隙之和,汇编语言,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

我在这个问题上被困得发疯。我们应该找到数组中的间隙之和。我已经编写了查找数组和的代码,但不知道如何查找间隙和。这是我的。所以差距是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 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)。然后减去从location
array
读取的
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