我有一个分配,我必须创建一个文本文件,例如:
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'标签的底部,直到那一刻都有效。如果你要对它进行评论,程序将恢复正常工作。
有人可以告诉那些导致问题的是什么吗?
代码(有很多评论,所以如果你把它粘贴在你自己的编辑器中可能会更容易理解):
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
答案 0 :(得分:0)
你归零esi
并且永远不会改变它。因此mov eax, [esi+ecx]
将访问无效内存。
代码在其他方面存在疑问:考虑到mov [esi+i], edi
是单个双字,i
如何合理?