当试图将数组加倍时,汇编中出现分段错误



我一直在试图修复这个像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

相关内容

  • 没有找到相关文章

最新更新