x86汇编中栈传字符串及长度参数触发段错误求助
段错误原因及修复方案
你的代码触发段错误的核心原因是print函数未正确建立栈帧:
- 调用
call print时,CPU会先把返回地址压入栈中 - 进入print函数后,你直接使用
ebp寄存器访问栈上的参数,但此时ebp并未被初始化(没有关联到当前栈顶),导致[ebp+4]、[ebp+8]指向非法内存地址,触发段错误。
同时还要注意参数的栈存储顺序:栈是向下生长的,先push的参数会位于更高的栈地址,你原代码里的参数偏移也搞反了。
修复后的代码
global main section .data var db "this is the message",0 varlen equ $- var section .text print: push ebp ; 保存旧的ebp寄存器值 mov ebp, esp ; 将ebp指向当前栈顶,建立稳定栈帧 mov eax, 4 mov ebx, 1 mov ecx, [ebp + 8] ; ebp+4是返回地址,ebp+8才是第一个传入的参数var mov edx, [ebp + 12] ; ebp+12是第二个传入的参数varlen int 0x80 pop ebp ; 恢复旧的ebp寄存器值 ret 8 ; 自动清理栈上的2个参数(每个占4字节,共8字节) main: push varlen push var call print mov eax, 1 mov ebx, 0 int 0x80
关键说明
- 栈帧建立的
push ebp; mov ebp, esp是x86汇编中访问栈参数的标准操作,确保ebp能稳定指向当前栈帧的起始位置,避免访问非法内存。 ret 8的作用是在返回时自动清理栈上的两个参数,等价于在call print后执行add esp, 8,保证main函数的栈平衡。
内容的提问来源于stack exchange,提问作者spyblock
相关产品推荐
相关产品推荐

