执行从 x86 程序集编译的程序时出现分段错误? [英] Segmentation fault when executing program compiled from x86 assembly?

查看:20
本文介绍了执行从 x86 程序集编译的程序时出现分段错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是汇编语言的新手,我必须实现一个函数,在我的例子中是 sin(x),它可以从 C 源文件中调用.我必须制作 2 个单独的文件:*.c 和 *.s在 ubuntu 上通过 gcc 编译时一切正常,但是当程序执行时它给我错误分段错误"...

I'm new to assembly language and I have to implement a function, in my case sin(x), that could be called from a C source file. I have to make 2 separate files: *.c and *.s When compiling through gcc on ubuntu all good, but when the program executes it gives me the error "Segmentation fault"...

要编译,我输入:

gcc -c -o sinc.o sinx.c -g3
gcc -c -o sins.o sinx.s -g3
gcc -o sinx sinc.o sins.o -g3

当我启动程序时:

./sinx

打印出来:

.......insert x:

我把 x 放进去,然后:

I put x in and then:

segmentation fault

然后它停止了.这是两个文件:

and it stops. Here are the two files:

/*-----------------------------------Sin[x]----------------------------------------*/

extern float Sin(float x);                                //extern assembly function

#include <stdio.h>                                             //necessary libraries

int main()                                                          // main function
{
    float x;                                      //allocate variable 'x' as a float
    float sine;                                //allocate variable 'sine' as a float

    printf("Calculate Sin[x], with 'x' in radians
");      //purpose of the program

    printf("Insert 'x': ");                                            //user prompt
    scanf("%f",&x);                                                //get input value

    sine=Sin(x);                                                   //calculate sin(x)

    printf("Sin[%f]=%f
",x,sine);                                     //print sin(x)

    return 0;                                                       //successful exit
}
/*----------------------------------------------------------------------------------*/

#---------------------------Sin[x]-----------------------------#
.data
.text
.globl Sin             #global function visible by main function

#function sumplus
sumplus:
   pushl  %ebp
   movl   %esp,%ebp
   fld1                                             #load 1 in ST(0)
   movl   12(%ebp),%ecx                                       #ecx=i
power:
   fmul   %st(0),%st(1)                   #ST(0)=ST(0)*ST(1),ST(1)=x
   loop   power                                #at the end ST(0)=x^i
   movl   12(%ebp),%ecx                                       #ecx=i
   xorl   %edx,%edx                           #reset edx used in mul
   movl   $1,%eax                                   #set accumulator
factorial:
   mul    %ecx                                          #eax=eax*ecx
   loop   factorial                               #at the end eax=i!
   pushl  %eax
   fild   -4(%ebp)                       #ST(0)=i!,ST(1)=x^i,ST(2)=x
   popl   %eax
   fdiv   %st(1),%st(0)                  #ST(1)=ST(1)/ST(0)=(x^i)/i!
   fld    8(%ebp)                      #load partial result in ST(0)
   fadd   %st(0),%st(2)                #ST(0)=updated partial result
   fstp   8(%ebp)               #store partial result into the stack
   fcomip %st(0),%st(0)                                      #pop i!
   fcomip %st(0),%st(0)                          #pop x^i/i!,ST(0)=x
   leave
   ret

#function summinus
summinus:
   pushl  %ebp
   movl   %esp,%ebp
   fld1                                             #load 1 in ST(0)
   movl   12(%ebp),%ecx                                       #ecx=i
power2:
   fmul   %st(0),%st(1)                   #ST(0)=ST(0)*ST(1),ST(1)=x
   loop   power2                               #at the end ST(0)=x^i
   movl   12(%ebp),%ecx                                       #ecx=i
   xorl   %edx,%edx                           #reset edx used in mul
   movl   $1,%eax                                   #set accumulator
factorial2:
   mul    %ecx                                          #eax=eax*ecx
   loop   factorial2                              #at the end eax=i!
   pushl  %eax
   fild   -4(%ebp)                       #ST(0)=i!,ST(1)=x^i,ST(2)=x
   popl   %eax
   fdiv   %st(1),%st(0)                  #ST(1)=ST(1)/ST(0)=(x^i)/i!
   fld    8(%ebp)                      #load partial result in ST(0)
   fsub   %st(0),%st(2)                #ST(0)=updated partial result
   fstp   8(%ebp)               #store partial result into the stack
   fcomip %st(0),%st(0)                                      #pop i!
   fcomip %st(0),%st(0)                          #pop x^i/i!,ST(0)=x
   leave
   ret

#function develop
develop:
   pushl %ebp
   movl  %esp,%ebp
   sub   $8,%esp                #allocate room for local variables
   movl  $9,-4(%ebp)       #store development-order,only odd values
   fldz                                          #load 0.0 in ST(0)
   fstp  -8(%ebp)           #store ST(0) and pop to collect results
Cycle:
   movl   -4(%ebp),%eax                    #eax=i,development-order
   xorl   %edx,%edx                       #reset edx because of div
   sub    $1,%eax                                              #i-1
   movl   $2,%ecx                                          #divisor
   div    %ecx                                   #eax=(i-1)/2,edx=0
   div    %ecx           #eax=((i-1)/2)/2,remainder edx=0 or edx!=0
   movl   %edx,%ecx                                  #ecx=remainder
   jecxz  Sumplus                                 #n even,(-1)^n=+1
Summinus:
   call   summinus                                 #n odd,(-1)^n=-1
   jmp    Restore                        #if sum- occured skip sum+
Sumplus:
   call   sumplus
Restore:
   movl   -4(%ebp),%ecx                            #restore counter
   sub    $2,-4(%ebp)                                 #update order
   loop   Cycle                                      #decrement ecx
   fcomip %st(0),%st(0)                                      #pop x
   fld    -8(%ebp)                       #load final result in ST(0)
   leave
   ret

#function sin
Sin:
   pushl %ebp
   movl  %esp,%ebp
   fld   8(%ebp)                   #push onto the stack 'x' value
   fldpi                           #load pi into ST(0),x in ST(1)
ControlPi:
   fcomi  %st(1)                                #compare pi and x
   jae    LoadNPi              #stop ControlPi, x is less than pi 
   fsub   %st(1),%st(0)                     #store (x-pi) in ST(1)
   jmp    ControlPi                            #return to control 
LoadNPi:            
   fimul   -1                           #(-pi) in ST(0),x in ST(1)                   
ControlPi2:
   fcomi  %st(1)                               #compare -pi and x
   jbe    PopStack        #stop ControlPi2, x is greater than -pi
   fadd   %st(1),%st(0)                     #store (x+pi) in ST(1)
   jmp    ControlPi2                           #return to control
PopStack:
   fcomip %st,%st(0)   #compare -pi to -pi then pop register stack
   call  develop                            #call develop function
   leave                                              #restore ebp
   ret                                                     #return

那么,错误在哪里?我怎么解决这个问题?谢谢.

So,where are the errors? How can I solve this problem? Thank you.

推荐答案

我建议创建一个非常简单的汇编语言函数,它什么都不做,只返回它传递的相同参数.这相当于 C 函数:

I would suggest creating a very simple assembly language function that does nothing but return the same argument it's passed. This would be equivalent to the C function:

float identity(float x) {
    return x;
}

完成这项工作将确保您在开始实际编写代码之前正确设置所有编译、组装、链接、调用约定等.一旦成功,编写一个函数将 1 添加到参数并返回.然后,在您进行一些练习之后,开始实现您的 Sin() 函数.到目前为止,对于汇编语言的新手来说,您所获得的代码实在是太多了.

Making this work will ensure that you have all the compiling, assembling, linking, calling conventions, etc all set up properly before you start actually writing code. Once that works, write a function to add 1 to the argument and return that. Then, start implementing your Sin() function after you've got some practice. What you've got so far is a heck of a lot of code for somebody new to assembly language.

这篇关于执行从 x86 程序集编译的程序时出现分段错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆