C++ 从C调用的nasm函数以分段故障结束

C++ 从C调用的nasm函数以分段故障结束,c++,nasm,C++,Nasm,我必须只使用一个条件跳转指令来查找数组中的最小-最大值 编译并链接下面的两个文件后,我得到了一个分段错误(内核转储),但我不明白为什么会这样 问题:是什么导致分段错误 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

我必须只使用一个条件跳转指令来查找数组中的最小-最大值

编译并链接下面的两个文件后,我得到了一个
分段错误(内核转储)
,但我不明白为什么会这样

问题:是什么导致分段错误


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;
}
#包括
#包括
使用名称空间std;
外部“C”void minmax(int n,int*tab,int*max,int*min);
int main(){
常数int rozmiar=100000;
里兹巴岛内的常数=10000;
int tab[rozmiar]={1,3,3,-65,3,123,4,32,342,22,11,32,44,12,324,43};
选项卡[rozmiar-1]=-1000;
最小整数,最大整数;
最小值=99999;
最大值=-99999;
时钟没有启动,停止;
开始=时钟();
对于(int i=0;i[esi]->更新最小值
添加esi,4;移动到另一个元素
循环lp;在所有元素上循环
最大值:
mov-eax,esi
ret
最小值:
电影电子数据交换
ret
pop esi;还原已用寄存器
波普ecx
流行ebp
返回给呼叫方

我不知道您到底想做什么,但汇编函数写得很差

试试这个:

   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

我不知道你到底想做什么,但是汇编函数写得很差

试试这个:

   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

我不知道你到底想做什么,但是汇编函数写得很差

试试这个:

   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

我不知道你到底想做什么,但是汇编函数写得很差

试试这个:

   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

长话短说

在使用
ret
之前,需要恢复堆栈

asm实现在许多层面上都有缺陷,但分段错误的原因是对
ret
的工作原理理解不足


无效使用
ret

ret
不会返回到最后一次跳转,它读取堆栈顶部的值,然后返回到该地址

跳转到
min:
max:
后,调用
ret
,此时应跳回循环

这意味着它将尝试返回堆栈顶部的地址,该地址肯定不是有效地址;您在输入函数时对其进行了修改

推ebp
mov ebp,esp;设置ebp
按下ecx;保存已使用的寄存器
按esi;注意,这是'ret'将尝试去的地方

长话短说:

在使用
ret
之前,需要恢复堆栈

asm实现在许多层面上都有缺陷,但分段错误的原因是对
ret
的工作原理理解不足


无效使用
ret

ret
不会返回到最后一次跳转,它读取堆栈顶部的值,然后返回到该地址

跳转到
min:
max:
后,调用
ret
,此时应跳回循环

这意味着它将尝试返回堆栈顶部的地址,该地址肯定不是有效地址;您在输入函数时对其进行了修改

推ebp
mov ebp,esp;设置ebp
按下ecx;保存已使用的寄存器
按esi;注意,这是'ret'将尝试去的地方

长话短说:

在使用
ret
之前,需要恢复堆栈

asm实现在许多层面上都有缺陷,但分段错误的原因是对
ret
的工作原理理解不足


无效使用
ret

ret
不会返回到最后一次跳转,它读取堆栈顶部的值,然后返回到该地址

跳转到
min:
max:
后,调用
ret
,此时应跳回循环

这意味着它将尝试返回堆栈顶部的地址,该地址肯定不是有效地址;您在输入函数时对其进行了修改

推ebp
mov ebp,esp;设置ebp
按下ecx;保存已使用的寄存器
按esi;注意,这是'ret'将尝试去的地方

长话短说:

在使用
ret
之前,需要恢复堆栈

asm实现在许多层面上都有缺陷,但分段错误的原因是对
ret
的工作原理理解不足


无效使用
ret

ret
不会返回到最后一次跳转,它读取堆栈顶部的值,然后返回到该地址

跳转到
min:
max:
后,调用
ret
,此时应跳回循环

这意味着它将尝试返回堆栈顶部的地址,该地址肯定不是有效地址;您在输入函数时对其进行了修改

推ebp
mov ebp,esp;设置ebp
按下ecx;保存已使用的寄存器
按esi;注意,这是'ret'将尝试去的地方

“我能写出这样的东西”:sth是什么?SEGFULT在minmax函数中发生了吗?您应该能够在gdb中运行程序,并计算出SEGFULT发生时的堆栈跟踪,以及是哪条指令导致了SEGFULT。@Spundun
sth
是一个工作不正常的函数,也不符合仅一个条件跳转的要求。相关:在将它们发送到asm函数的深渊之前初始化
max
min
如何?现在是UB。是的,这是一个很好的id