【发布时间】:2017-06-22 14:38:24
【问题描述】:
在以下代码中,当我取消注释任何 push 指令时,我在运行可执行文件时收到错误 Segmentation fault (core dumped)。我试图查明错误原因,但尚未找到原因。
section .data
; Message contains app purpose
msg db 'This app calculates 2^3+5^2',0x0a
mlen equ $-msg
msg1 db 'Computation is done',0x0a
lmsg1 equ $-msg1
num1 dd 2
lnum1 equ $-num1
pow1 dd 3
lpow1 equ $-pow1
num2 dd 5
lnum2 equ $-num2
pow2 dd 2
lpow2 equ $-pow2
section .text
global _start
_start:
xor edx, edx ; clear registers
xor ecx, ecx
xor ebx, ebx
xor eax, eax
xor esi, esi
xor edi, edi
xor esp, esp
xor ebp, ebp
mov edx, mlen
mov ecx, msg
mov ebx, 1
mov eax, 4
int 0x80 ; print message
mov edx, dword [pow2]
mov ecx, dword [num2]
mov ebx, dword [pow1]
mov eax, dword [num1]
;push edx
;push ecx ; --> When I un-comment any push command,
;push ebx ; --> I receive: Segmentation fault (core dumped)
;push eax ;
jmp end
end:
mov edx, lmsg1 ; length
mov ecx, msg1 ; memory location
mov ebx, 1
mov eax, 4
int 0x80 ; print a newline i.e. 0x0a
mov ebx, 0
mov eax, 1
int 0x80
【问题讨论】:
-
什么是
pushed 必须是poped,否则你会不平衡堆栈。这是段错误的常见原因。无论如何,push指令的目的是什么?你想做什么?另外,顺便说一句,你不需要imp end;反正执行到了那里! -
xor esp, esp你将堆栈指针归零,呵呵。如果您想使用堆栈,您确实意识到这有点糟糕,对吧? -
push将要写入堆栈,而堆栈是esp指向的位置。如果将其归零,则在尝试使用它时会出现段错误,而不是在归零时。 -
注意:当 ESP 设置为零时,推送 4 个字节将导致它回绕到 0xFFFFFFFC,然后存储 4 个字节。该地址位于内核空间中,因此推送会导致页面错误(CPL=3 代码试图写入主管页面)。页面错误被转换为信号(SIGSEGV),从而导致
Segmentation fault错误消息。 -
堆栈和其他内存一样是普通内存,
push/pop只是方便的指令,类似于:push eax=sub esp,4mov [esp],eax(但push不会修改标志,而且它有点原子性,请参阅指令参考指南了解最细微的细节......所以它不是完全相同的东西)。
标签: assembly x86 segmentation-fault nasm