程序集和 C 代码中的分段错误(内核转储)

Segmentation fault (core dumped) in Assembly and C code

提问人:James Hou 提问时间:11/5/2023 最后编辑:JesterJames Hou 更新时间:11/5/2023 访问量:79

问:

我是 C 和汇编的新手,我很难弄清楚为什么我的代码中会出现分段错误。在当前的任务中,我必须创建 4 个汇编程序,这些程序链接到我的主 c 程序。我只在处理第一个函数,即 sumOfPowers 函数,但我在那里遇到了分段错误。这是我的主要功能:

#include "something.c"
#include <stdio.h>
#include <stdlib.h>
typedef struct Customer {
  int id;
  int age;
  int payments[5];
} CUSTOMER;

typedef struct Employee {
  char name[8];
  int salary;
} EMPLOYEE;

int sumOfPowers(int n);                                 //this function should find the following sum: 1^2 + 2^2 + 3^2 + 4^2 + ... + n^2
// int compareAges(CUSTOMER* a, CUSTOMER* b);              //this function should test if  a->age == b->age. it returns 1 if they are equal; 0 otherwise.
// int findPaymentsSum(CUSTOMER* c, int num_of_pamyments); //this function should find the sum of all payments made by a given customer
// int findSalariesSum(EMPLOYEE e[], int size);            //this function should find the sum of salaries in a given array of employees

int main() {

  // TestCase-1
  printf("The sum is: %d\n", sumOfPowers(3));

  // TestCase-2
  /*
  CUSTOMER* a1=malloc(sizeof(CUSTOMER));
  CUSTOMER* a2=malloc(sizeof(CUSTOMER));
  CUSTOMER* a3=malloc(sizeof(CUSTOMER));
  a1->age=25;
  a2->age=30;
  a3->age=25;
  printf("The result of the comparison is: %d\n",compareAges(a1,a2));
  printf("The result of the comparison is: %d\n",compareAges(a1,a3));
  */

  // TestCase-3
  /*
  CUSTOMER* cstmr=malloc(sizeof(CUSTOMER));
  cstmr->id=101;
  cstmr->age=30;
  cstmr->payments[0]=1500;
  cstmr->payments[1]=1500;
  cstmr->payments[2]=2000;
  cstmr->payments[3]=500;
  cstmr->payments[4]=300;
  printf("The sum of all payments is: %d\n",findPaymentsSum(cstmr, 5));
  */

  // TestCase-4

  // EMPLOYEE e1={"jame",2000}, e2={"sara",3000}, e3={"alic",2500},
  // e4={"mark",3200}; EMPLOYEE employees[4]={e1,e2,e3,e4}; printf("The sum of
  // salaries is: %d\n",findSalariesSum(employees,4));
} 

这是我的sumOfPowers.s函数:

 .globl sumOfPowers

sumOfPowers:
    push %rbp
    mov %rsp, %rbp

    # Input: n in %rdi
    # Output: Result in %rax

    # Initialize x to 0
    mov %rax, 0

    # Initialize i to 1
    mov %rcx, 1

loop_start:
    # Calculate i^2
    mov %rdx, %rcx     # Move the value of i from %rcx to %rdx
    imul %rdx, %rdx    # Calculate i^2 and store it in %rdx 

    # Add i^2 to x
    add %rax, %rdx

    # Increment i
    inc %rcx

    # Check if we've reached the end of the loop
    cmp %rcx, %rdi     # Compare the current value of i (in %rcx) with n (in %rdi)
    jle loop_start

    pop %rbp

    # The result is now in %rax, you can return it
    ret

我尝试使用不同的寄存器,但没有任何效果。需要注意的是,我使用的是 Repl.it 因此我使用的是那里使用的任何计算机体系结构。

C 程序集 分段故障 x86-64

评论

2赞 Jester 11/5/2023
AT&T语法使用源,目标顺序。此外,您需要在 immediates 上使用前缀。$
0赞 Raymond Chen 11/5/2023
看起来您使用的是 Intel 语法(没有操作数大小后缀),在这种情况下,您正朝着错误的方向前进mov %rsp, %rbp
1赞 Peter Cordes 11/5/2023
@RaymondChen:当寄存器操作数暗示大小时,AT&T语法不需要操作数大小后缀。只有在没有寄存器操作数的情况下,才需要而不是。这是一种风格选择;我更喜欢将 size 保留为隐式,就像在 Intel 语法中一样,我尽可能省略 size。但是,是的,OP 似乎确实编写了除了 RBP 帧指针设置之外的所有内容,就好像它是 Intel 语法一样(基于操作顺序和缺乏对 immediates 的修饰),但忘记使用 .movlmovmovl $1, (%rdi)negb (%rsi)dword ptr$.intel_syntax noprefix
1赞 Jester 11/5/2023
它以库存 at&t 模式组装。缺失会导致生成内存引用,然后该引用将与观察到的行为进行故障匹配。$
1赞 Peter Cordes 11/5/2023
@RaymondChen:这是有效的AT&T语法,适用于与注释不匹配的无用指令,例如具有寻址模式的存储到绝对地址。你是对的,不会组装,因为即时不能成为目的地,但如果没有它,它就不是即时的。mov %rcx, 11[disp32]mov %rcx, $1$

答: 暂无答案