c - 段错误 - 原因是什么

标签 c arrays assembly segmentation-fault arguments

我正在学习 32 位汇编,我需要代码方面的帮助。我试图将 4 放入索引 3 处的表中,该表通过参数传递给汇编代码。

.code32

.equ    KERNEL, 0x80    # Linux system functions entry
.equ    WRITE,  0x04    # write data to file function
.equ    EXIT,   0x01    # exit program function

.equ    STDOUT, 1


.equ argTab,    8
.equ argLicz,   12
.equ argN,  16
.equ argZakres, 20

.text
    .globl przelicz
    .type przelicz, @function

przelicz:

    pushl %ebp
    movl %esp, %ebp

    movl $2, %ecx
    movl $4, %ebx

    movl argTab(%ebp), %edx
    movl %ebx, (%edx,%ecx,4)


    movl %ebp, %esp
    popl %ebp

ret

我用C代码执行它:

#include <stdio.h>

int main(){
    const static int n = 5;
    int tab[n];
    int a;
    for(a = 0; a < n; ++a){
        tab[a] = a;
    }
    int licz[n];

    przelicz(tab, licz, 50, 50);

    for(a = 0; a < n; ++a){
        //printf("%d ", licz[a]);
    }
}

当我运行它时,出现错误:段错误(代码已转储)。我读到我正在尝试访问不存在的内存。我该如何解决这个问题?

最佳答案

正如我上面评论的,问题在于该进程被编译为 64 位进程。这是一个问题,原因有两个:

  1. x64-linux 使用与 x86-linux 不同的系统调用表。由于您没有调用直接系统调用,因此这可能不是错误 - 但需要注意。 例如,在 x64-linux 中,write 不是 0x04,而是 0x01。 (有关 x64-linux 系统调用号,请参阅 this table)。
  2. 显然,x64-linux 具有更大的指针大小。因此,当加载 32 位地址时,该地址的随机 32 位上半部分可能指向任何位置。这也会影响函数堆栈中的值(它们调用包含 8 字节偏移量,而不是 4),这很可能是导致此代码中出现问题的原因。

关于c - 段错误 - 原因是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17202332/

相关文章:

c - Arduino C 多维数组切换

c - 编译内联 MMX 汇编程序时出错 : Suffix or operands invalid

c - 如何将 * char 复制到静态字符串数组,printf 产生奇怪的输出,

c++ - 我的方法不反转字符数组

debugging - SPARC 单步执行模式

您可以在汇编中添加预处理器指令吗?

c - 从 C 中的 FIFO 读取 : select() doesn't return?

C 客户端-代理-服务器文件传输仅发送文件的一部分

c - 笔连接样式未应用于形状的所有角

ios - 如何在 Swift 中使用 SCNetworkReachability