You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NASM汇编向C函数传递字符串指针数组时遇段错误求助

问题描述

我是汇编新手,正在完成课程任务:通过NASM汇编代码向C函数传递字符串指针数组,调用display函数打印数组中的字符串(validate函数可忽略)。在WSL环境下运行代码,GDB调试时能看到字符串输出,但程序触发SIGSEGV段错误。怀疑是指针传递或内存操作有误,以下是相关信息:

报错信息

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7e32540 in _int_malloc (av=av@entry=0x7ffff7fa7c80 <main_arena>, bytes=bytes@entry=640) at ./malloc/malloc.c:4375
4375    ./malloc/malloc.c: No such file or directory.
(gdb) where
#0  0x00007ffff7e32540 in _int_malloc (av=av@entry=0x7ffff7fa7c80 <main_arena>, bytes=bytes@entry=640) at ./malloc/malloc.c:4375
#1  0x00007ffff7e32a49 in tcache_init () at ./malloc/malloc.c:3245
#2  0x00007ffff7e3325e in tcache_init () at ./malloc/malloc.c:3241
#3  __GI___libc_malloc (bytes=bytes@entry=1024) at ./malloc/malloc.c:3306
#4  0x00007ffff7e0cc24 in __GI__IO_file_doallocate (fp=0x7ffff7fa8780 <_IO_2_1_stdout_>) at ./libio/filedoalloc.c:101
#5  0x00007ffff7e1bd60 in __GI__IO_doallocbuf (fp=fp@entry=0x7ffff7fa8780 <_IO_2_1_stdout_>) at ./libio/libioP.h:947
#6  0x00007ffff7e1afe0 in _IO_new_file_overflow (f=0x7ffff7fa8780 <_IO_2_1_stdout_>, ch=-1) at ./libio/fileops.c:744
#7  0x00007ffff7e19755 in _IO_new_file_xsputn (n=22, data=<optimized out>, f=<optimized out>) at ./libio/libioP.h:947
#8  _IO_new_file_xsputn (f=0x7ffff7fa8780 <_IO_2_1_stdout_>, data=<optimized out>, n=22) at ./libio/fileops.c:1196
#9  0x00007ffff7e0ef9c in __GI__IO_puts (str=0x404058 "This is the original.\n") at ./libio/libioP.h:947
#10 0x0000000000401307 in display ()
#11 0x00000000004011bb in loop ()
#12 0x00007ffff7db7d90 in __libc_start_call_main (main=main@entry=0x401180 <main>, argc=argc@entry=1, argv=argv@entry=0x7fffffffdf18) at ../sysdeps/nptl/libc_start_call_main.h:58
#13 0x00007ffff7db7e40 in __libc_start_main_impl (main=0x401180 <main>, argc=1, argv=0x7fffffffdf18, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffdf08)
at ../csu/libc-start.c:392
#14 0x00000000004010b5 in _start ()

原NASM代码

;Extern ceasar ;calling my project3
;All funcitons below are writen in C
;Extern read_message ;read message from user
Extern display ;display the strings
;Extern decrypt ;decypt function
extern freeUp ;free memory
extern printf
extern validate
extern fprintf

section .data
defaultMessage db "This is the original.", 10, 0
len_Mess equ $-defaultMessage
fmtpf db "%d", 10, 0

section .bss
array resq 10


section .text

global main

main:

mov r8, 64
mov r9, 0
xor r10,r10
mov r11, 10
loop:

mov qword[array + r10], defaultMessage
add r10, r8
add r9, 1
cmp r9, r11
JLE loop
mov rdi, array
call display
call validate
mov [array], rax


exit:
mov rax, 60
mov rdi, [array]
call freeUp
xor rdi, rdi
syscall

原C代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* validate(){
int buffer = 256;
int pos = 0;
    char* cmd = malloc(sizeof(char) * buffer);
    
    int cha;
        int cont = 1;
    
        while(cont == 1){
                cha = fgetc(stdin);
    
                if(cha == EOF || cha == '\n'){
                        cmd[pos] = '\0';
                        cont = 0;
                }
                else{
                        cmd[pos] = cha;
                }
    
                pos++;
    
                if(pos >= buffer){
                        buffer += 256;
                        cmd = realloc(cmd, buffer);
    
                }
        }
    
        return cmd;

}
void display(char** Array){
        for(int i = 0; i < 10; i++){
                printf("%s\n", Array[i]);
        }
        return;
}

void freeUp(char* msg){
free(msg);
}

需求:实现从汇编向C传递数组并打印所有字符串,排查并解决段错误问题。


错误原因分析
  • 数组元素偏移量错误:x86_64架构下指针长度为8字节,但代码中用mov r8, 64作为元素间隔,导致每次写入数组时跳过64字节,远超array resq 10(仅80字节)的范围,破坏了BSS段外的内存,干扰了libc内部内存管理结构,触发malloc时的段错误。
  • 循环次数超出数组容量:设置r11=10且用JLE loop作为循环条件,会导致循环执行11次(r9从0到10),但数组仅能容纳10个元素,进一步加剧内存越界。
  • C代码printf格式问题:原代码中printf("%s ", Array[i])是无效转义,需改为printf("%s\n", Array[i])避免输出异常。

修复后的代码

修正后的NASM代码

;Extern ceasar ;calling my project3
;All funcitons below are writen in C
;Extern read_message ;read message from user
Extern display ;display the strings
;Extern decrypt ;decypt function
extern freeUp ;free memory
extern printf
extern validate
extern fprintf

section .data
defaultMessage db "This is the original.", 10, 0
len_Mess equ $-defaultMessage
fmtpf db "%d", 10, 0

section .bss
array resq 10  ; 10个8字节指针,共80字节


section .text

global main

main:
    mov r8, 8          ; x86_64下指针为8字节,设置正确偏移量
    mov r9, 0
    xor r10, r10
    mov r11, 10
loop:
    mov qword[array + r10], defaultMessage
    add r10, r8
    add r9, 1
    cmp r9, r11
    JL loop            ; 改为JL,循环10次(r9从0到9),避免越界
    
    mov rdi, array
    call display
    
    ; 若不需要validate和freeUp逻辑,可暂时注释以确保核心功能正常
    ; call validate
    ; mov [array], rax

exit:
    ; 注意:defaultMessage在只读数据段,不能free;若要free validate返回的指针,需确保逻辑正确
    ; mov rdi, [array]
    ; call freeUp
    
    mov rax, 60
    xor rdi, rdi
    syscall

修正后的C代码(主要修正printf格式)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* validate(){
    int buffer = 256;
    int pos = 0;
    char* cmd = malloc(sizeof(char) * buffer);
    
    int cha;
    int cont = 1;
    
    while(cont == 1){
        cha = fgetc(stdin);

        if(cha == EOF || cha == '\n'){
            cmd[pos] = '\0';
            cont = 0;
        }
        else{
            cmd[pos] = cha;
        }

        pos++;

        if(pos >= buffer){
            buffer += 256;
            cmd = realloc(cmd, buffer);
        }
    }
    return cmd;
}

void display(char** Array){
    for(int i = 0; i < 10; i++){
        printf("%s", Array[i]);  // defaultMessage已包含换行符,无需额外添加\n;也可保持printf("%s\n", Array[i])
    }
    return;
}

void freeUp(char* msg){
    free(msg);
}

验证方法

在WSL中执行以下命令编译运行:

nasm -f elf64 your_asm_file.asm -o asm.o
gcc asm.o your_c_file.c -o program
./program

程序会正常打印10次This is the original.,且无段错误触发。

内容的提问来源于stack exchange,提问作者Jabril_hall

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 02:32:50