我一直在试图修复这个像5个小时。我试图得到它,以便在5个元素输入到数组中之后数组翻倍并将旧元素复制到新元素中并继续直到你停止然后输出统计数据,出于某种原因在输入5个数字之后,我只是得到一个分割错误
%define ARRAY_SIZE 5
%define ELEMENT_SIZE 4
%define EOF -1
segment .data
inputPrompt: db "Enter int value (ctrl-d to stop): ",0
intFormat: db "%d",0
output: db "Array[%d] = %d",10,0
dbout: db 10, 10,"[%d]",10,10,0 ; This is just for debugging output
newline: db 10,0 ; For whenever we need a newline
numElements: db "Number of elements: %d",10,0
outputSum: db "sum of elements: %d",10,0
minValue: db "Min value: %d",10,0
maxValue: db "Max value: %d",10,0
segment .bss
arrayPtr: resq 1 ; pointer to our array
intInput: resd 1
segment .text
global asm_main
extern printf, scanf, calloc
createNewArray:
mov rdi, [arrayPtr]
mov rsi, ARRAY_SIZE
add rsi, rsi ; Double the array size
mov rdx, ELEMENT_SIZE
call calloc
mov rbx, [arrayPtr] ; Move the old array elements to the new array
mov rcx, ARRAY_SIZE
cld
rep movsd
mov [arrayPtr], rax ; Save the new array pointer
ret
asm_main:
enter 0,0
;; Get memory for our array
;; Give calloc() number of element and element size
;; and calloc returns a pointer to zerioized memory
mov rdi, ARRAY_SIZE
mov rsi, ELEMENT_SIZE
call calloc
mov [arrayPtr], rax
mov rdi, [arrayPtr] ; Will use RDI and stosd to write the array
mov rcx, ARRAY_SIZE
mov r15, 0 ; R15 counts how many elements in our array
cld
inputLoop:
push rcx ; Save RCX and RDI across printf/scanf calls
push rdi
mov rdi, inputPrompt
call printf
mov rdi, intFormat
mov rsi, intInput
call scanf
cmp eax, EOF ; Did scanf() return -1 (didn't read anything?)
je inputDone
inc r15 ; O/w count another element & store it
cmp r15, ARRAY_SIZE ; Check if we've filled up the current array
jl arrayNotFull ; O/w, create a new array
call createNewArray
mov rdi, [arrayPtr] ; Update the pointers and sizes
mov rcx, r15
arrayNotFull:
xor rax, rax ; Clear out RAX for stosd to write array to mem
mov eax, [intInput]
pop rdi ; Restore RDI for stosd
stosd
pop rcx ; Restore RCS for loop instruction
loop inputLoop
inputDone: ; Let's get ready to print
mov rdi, newline
call printf
mov rsi, [arrayPtr] ; Will use RSI and lodsd to read the array
mov rcx, r15 ; Store actual array size to RCX
mov rbx, 0
cld
printLoop:
xor rax, rax
xor rdx, rdx
lodsd
push rcx ; Save RCX and RSI across printf call
push rsi
mov rdi, output
mov rsi, rbx
movsx rdx, eax
call printf
inc rbx
pop rsi ; Restore RCX and RSI
pop rcx
loop printLoop
je printStats
printStats:
mov rdi, newline
call printf
mov rdi, numElements
mov rsi, r15
call printf
mov rax, 0 ; Initialize the sum to zero
mov rsi, [arrayPtr] ; Get the address of the array
mov rcx, r15 ; Store actual array size to RCX
cld
xor rdx, rdx ; Clear out RDX for the first add instruction
mov rax, 0 ; Initialize the sum to zero
mov rsi, [arrayPtr] ; Get the address of the array
mov rcx, r15 ; Store actual array size to RCX
cld
sumLoop:
lodsd ; Load the next element of the array into EAX
add rax, r8 ; Add the current sum to EAX
mov r8, rax ; Store the updated sum in R8
loop sumLoop
mov rdi, outputSum
mov rsi, r8
call printf
; Find the minimum value in the array
mov rax, [arrayPtr] ; Load the base address of the array into RAX
mov ebx, [rax] ; Load the first element of the array into EBX
mov rcx, r15 ; Loop counter will be the number of elements
dec rcx ; Decrement RCX since we've already loaded the first element
mov rsi, [rax] ; Initialize RSI to the first element
loopStart:
add rax, ELEMENT_SIZE ; Move the pointer to the next element
cmp [rax], ebx ; Compare the value at the current pointer to the minimum value
jge loopEnd ; If the value is greater than or equal to the minimum, skip to the end of the loop
mov ebx, [rax] ; Otherwise, update the minimum value
mov rsi, rax ; and store the address of the minimum value in RSI
loopEnd:
loop loopStart ; Repeat for the remaining elements of the array
mov rdi, minValue
mov rsi, rbx
call printf
; Find the maximum value in the array
mov rax, [arrayPtr] ; Load the base address of the array into RAX
mov ebx, [rax] ; Load the first element of the array into EBX
mov rcx, r15 ; Loop counter will be the number of elements
dec rcx ; Decrement RCX since we've already loaded the first element
mov rsi, [rax] ; Initialize RSI to the first element
loopStartd:
add rax, ELEMENT_SIZE ; Move the pointer to the next element
cmp [rax], ebx ; Compare the value at the current pointer to the maximum value
jle loopEndd ; If the value is less than or equal to the maximum, skip to the end of the loop
mov ebx, [rax] ; O/w, update the maximum value to the current value
mov rsi, rax ; Store the address of the current maximum value
loopEndd:
loop loopStartd
mov rdi, maxValue
mov rsi, rbx
call printf
mov rax, 0
leave
ret
我试图保存新的数组指针[arrayPtr], rax,但它似乎没有做任何事情或我做错了什么,任何帮助将是伟大的。
callloc如何工作?寄存器没有以一致的方式使用。
第一次(在main中)使用它:
mov rdi, ARRAY_SIZE mov rsi, ELEMENT_SIZE call calloc ; -> RAX
但是第二次(在createNewArray)你使用它像:
mov rdi, [arrayPtr] mov rsi, ARRAY_SIZE add rsi, rsi ; Double the array size mov rdx, ELEMENT_SIZE call calloc ; -> RAX
之后的rep movsd
既没有给出合适的RSI,也没有给出合适的RDI。分割故障的原因…
mov rbx, [arrayPtr] ; Move the old array elements to the new array mov rcx, ARRAY_SIZE cld rep movsd mov [arrayPtr], rax ; Save the new array pointer
在inputLoop你调用createNewArray甚至在第一个数组中存储第五个数组元素之前。这是你上面提到的rep movsd
不能正常工作的另一个原因。
你不应该等到inputDone才想要创建第二个数组吗?
也许是个主意
如果你知道你无论如何都要复制数组,为什么不在main中分配双倍的内存,然后一次存储到两个数组中:
mov eax, [intInput]
pop rdi ; Restore RDI for stosd
mov [rdi + ELEMENT_SIZE * ARRAYSIZE], eax ; Store in 2nd array
stosd ; Store in 1st array