назм функция, вызванная из C, заканчивается segfaulting

Я должен найти минимальные максимальные значения в массиве, используя только одну директиву условного перехода.

После компиляции и связывания двух файлов ниже я получаю Segmentation Fault (core dumped), но я не понимаю, почему это так.

Вопрос: Что вызывает ошибка сегментации?


main.cpp

#include <cstdio>
#include <time.h>

using namespace std;
extern "C" void minmax(int n, int * tab, int * max, int * min);

int main(){
const int rozmiar = 100000;
const int liczba_powtorzen = 10000;

int tab[rozmiar] = {1, 3, 3, -65, 3, 123, 4, 32, 342, 22, 11, 32, 44, 12, 324, 43};
tab[rozmiar-1] = -1000;

int min, max;

min = 99999;
max = -99999;clock_t start, stop;
start = clock();

for(int i=0; i<liczba_powtorzen; i++){
minmax(rozmiar, tab, &max, &min);
}

printf("min = %d    max = %d\n", min, max);

stop = clock();
printf("\n time = %f ( %d cykli)", (stop - start)*1.0/CLOCKS_PER_SEC, (stop - start));

return 0;
}

minmax.asm

global minmax               ; required for linker and NASM

section .text              ; start of the "CODE segment"
minmax:
push ebp
mov ebp, esp        ; set up the EBP
push ecx            ; save used registers
push esimov ecx, [ebp+8]    ; array length n
mov esi, [ebp+12]   ; array address
mov eax, [ebp+16]   ;max
mov edi, [ebp+20]   ; minlp:     add eax, [esi]  ; fetch an array element
cmp eax, [esi]
jl max          ; max<[esi] ->update max
cmp edi, [esi]
jg min          ; min>[esi] ->update min
add esi, 4      ; move to another element
loop lp         ; loop over all elements

max:
mov eax, esi
ret

min:
mov edi, esi
ret

pop esi             ; restore used registers
pop ecx
pop ebp
ret                 ; return to caller

0

Решение

Я не знаю, что именно вы пытаетесь сделать, но функция ассемблера написана плохо.

Попробуй это:

   push ebp
mov ebp, esp        ; set up the EBP
push ecx            ; save used registers
push esi

mov ecx, [ebp+8]    ; array length n
mov esi, [ebp+12]   ; array address

mov eax, 0x80000000
mov edi,[ebp+16]
mov [edi], eax
mov eax, 0x7fffffff
mov edi,[ebp+20]
mov [edi], eax

lp:
mov edi,[ebp+16]
lodsd
cmp [edi], eax
jg short _min_test
mov [edi], eax

_min_test:
mov edi,[ebp+20]
cmp [edi], eax
jl short _loop
mov [edi], eax
_loop:
loop lp

pop esi             ; restore used registers
pop ecx
pop ebp
ret                 ; return to caller
0

Другие решения

Короче:

Вам необходимо восстановить стек перед использованием ret,

Ваш как м реализация ошибочна на многих уровнях, но причина вашего ошибка сегментации плохое понимание того, как ret работает.


Неправильное использование ret

ret не возвращает вас к последнему Прыгать, он читает значение, которое находится на вершине стека, и возвращается по этому адресу.

После того, как вы прыгаете либо min: или же max:, ты звонишь retгде вы должны прыгать обратно в петлю.

Это означает, что он будет пытаться вернуть вернуться к адресу в верхней части стека, который, безусловно, не является допустимым адресом; Вы изменили его при входе в функцию.

push ebp
mov ebp, esp        ; set up the EBP
push ecx            ; save used registers
push esi            ; note, this is where `ret` will try to go
3

По вопросам рекламы [email protected]