Loops x86 NASM程序中的分段错误

Loops x86 NASM程序中的分段错误,loops,assembly,x86,segmentation-fault,nasm,Loops,Assembly,X86,Segmentation Fault,Nasm,我有一个任务,必须创建一个文本文件,例如: 4 5 3 6 7 8 2 3 1 8 9 6 3 4 2 1 9 其中“4”定义了行/列的数量,并在NASM中编写了一个程序来查找对角线数字的总和,因此在本例中: 5 + 2 + 6 + 3 很明显,它会返回总数,22 我很确定我已经准备好了。我获取文件的输入,并使用文件中的第一个数字来定义文件的尺寸。因此,如果第一个数字是4,则文件的维度是4^2+1(1表示第一个数字)。n^2+1也是执行下一段的循环的退出条件: 此时,我使用fscanf()逐

我有一个任务,必须创建一个文本文件,例如:

4
5 3 6 7
8 2 3 1
8 9 6 3
4 2 1 9
其中“4”定义了行/列的数量,并在NASM中编写了一个程序来查找对角线数字的总和,因此在本例中:

5 + 2 + 6 + 3
很明显,它会返回总数,22

我很确定我已经准备好了。我获取文件的输入,并使用文件中的第一个数字来定义文件的尺寸。因此,如果第一个数字是4,则文件的维度是4^2+1(1表示第一个数字)。n^2+1也是执行下一段的循环的退出条件:

此时,我使用fscanf()逐个遍历文件并将其添加到数组中。在此之后,我需要做的就是获取数组的每个n+1元素(在本例中,n=4),直到到达数组的末尾,然后将它们全部相加

最后一段都发生在底部的“.diagonals”标签中,在这一点之前,一切都正常。如果你把它注释掉,程序就会恢复正常工作

有人能说出是什么引起了问题吗

代码(有很多注释,因此如果您将其粘贴到自己的编辑器中,可能会更容易理解):


您可以将esi设置为零,并且从不更改它<代码>mov eax、[esi+ecx]将因此访问无效内存


代码在其他方面是可疑的:
mov[esi+i],考虑到
i
是单个dword,edi
如何合理?

我不使用nasm,因此语法可能是正确的;但是当你推n时,你确定这推了&n(应该是这样),而不是n的值吗?我想是的。在我添加“对角线”标签之前,程序所做的全部工作是在从文件中解析值后输出数组。但它当时工作得很好,所以我认为应该是在那一点之后。在我的程序的一开始,我将esi设为零,但后来它包含了从文件解析的数字数组。我在“.printElement”中使用esi,它在那里工作得很好。在循环的每次迭代中,我都会向它添加4个元素,它只是一个偏移量,用于将edi移动到数组的下一个元素。
esi
在这个程序中没有写入,除了归零。如果有其他代码,请说明。至于
i
:它是一个标签,
[esi+i]
将使用标签的地址,而不是存储在那里的值。哦,现在我看到了。你完全正确,我将不得不完全重组“.对角线”的工作方式。谢谢你的帮助。
extern  fopen
extern  fclose
extern  fscanf
extern  printf

global  main

SEGMENT .data
n:                      DD      0
i:                      DD      0
x:                      DD      0                       ; variable for first digit of the file, which determines the number of rows/columns in the file
loopCounter: DD 0                       ; will be set to (n-1) where n is the first number in the file
sum1:           DD      0
sum2:           DD      0
format:         DD      "%d",0
formatInt:      DD      "%d ",0
readmode:       DD      "r", 0
filename:       DD      "hw5_2.dat", 0

SEGMENT .text
main:

        push    readmode                ; push "r"
        push    filename                ; filehandle
        call    fopen                   ; open file, returns pointer to file in eax
        add             esp, 8                  ; balance stack

        xor             esi, esi                ; clear esi
        xor             ecx, ecx                ; clear ecx
        mov             ebx, eax                ; move pointer to file to ebx
        jmp             .fileCycle

.firstLoop:                                     ; this is the first time the loop has run so it must determine the first value to use for the number of rows/columns

        xor             eax, eax                ; clear eax, just in case
        mov             eax, edi                ; move first number from file into eax

        mov             [loopCounter], eax      ; loopCounter = 4
        sub             [loopCounter], dword 1
        ;mov            [x], edi                ; move it also into [x], may need it later
        mul             eax                             ; eax = eax*eax
        mov             edx, eax                ; move result to edx

        mov             [x], eax                ; also move result to [x]
        add             [x], dword 4    ; add 4 to [x], this will become the offset later when adding the diagonals together


        inc             eax                             ; number of elements is n^2 + 1, so eax must be incremented
        inc             ecx                             ; increment loop counter, as this method runs before it can happen in the loop
        jmp             .fileCycle              ; resume loop, this method will not run again

.fileCycle:                                     ; this method cycles through the file and adds all the elements one by one into the esi register

        cmp             ecx, eax                ; end of file?
        ;je             .finished              
        je              .diagonals              ; YES - time to find diagonals

        push    eax
        push    ebx
        push    ecx
        push    edx

        push    n                               ; store scanned value in n
        push    format                  ; store as int
        push    ebx                             ; get input from file pointed to by eax
        call    fscanf
        add             esp, 12                 ; balance stack

        mov             edi, [n]                ; move value at n into edi
        mov             [esi+i], edi    ; store values in file as an array of ints located at esi

.printElement:

        push    dword [esi+i]   ; pass current element of array by value
        push    formatInt               ; pass format argument
        call    printf                  ; print current element
        add             esp, 8                  ; balance stack

        pop             edx
        pop             ecx
        pop             ebx
        pop             eax

        add             [i], dword 4    ; increment array index
        cmp             ecx, dword 0    ; is this the first time going through the loop?
        je              .firstLoop              ; YES - firstLoop method must be run

        inc             ecx                             ; inc loop counter     
        jmp             .fileCycle              ; NO - keep looping

.diagonals:                                     ; calculate the first diagonal sum
        xor             eax, eax                ; clear certain registers to be reused
        xor             ecx, ecx
        xor             edi, edi

        mov             ecx, dword 4    ; start the counter at 4 so it grabs the 2nd number of the array first
.L1:
        cmp             edi, [loopCounter]      ; compare edi (local loop counter) to loopCounter (the number of diagonals to add)
        je              .finished                       ; counters are equal - program finished

        mov             eax, [esi+ecx]  ; move next diagonal element into eax
        add             [sum1], eax             ; add it to the sum

        add             ecx, [x]                ; ecx += 20, 20 in this case is the dword offset to get the next diagonal
        inc             edi                             ; inc loop counter     


.finished:

        push    ebx
        call    fclose                  ; close the file
        add             esp, 4

        ret