- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
section .text
global _start
_start:
nop
main:
mov eax, 1
mov ebx, 2
xor eax, eax
ret
我用这些命令编译:
nasm -f elf main.asm
ld -melf_i386 -o main main.o
当我运行代码时,Linux 抛出一个段错误
(我使用的是 Linux Mint Nadia 64 位)。为什么会产生这个错误?
最佳答案
因为 ret
不是在 Linux、Windows 或 Mac 中退出程序的正确方法!!!!
_start
不是函数,堆栈上没有返回地址,因为没有要返回的用户空间调用者。用户空间中的执行从这里开始(在静态可执行文件中),在进程入口点。 (或者使用动态链接,它在动态链接器完成后跳转到这里,但结果相同)。
在 Linux/OS X 上,堆栈指针指向 argc
在进入_start
(有关进程启动环境的更多详细信息,请参阅 i386 或 x86-64 System V ABI 文档);内核在启动用户空间之前将命令行参数放入用户空间堆栈内存中。 (因此,如果您确实尝试 ret
,EIP/RIP = argc = 一个小整数,而不是有效地址。如果您的调试器在地址 0x00000001
或其他地方显示错误,这就是原因。)
对于 Windows,它是 ExitProcess
而 Linux 是系统调用 - int 80H
使用 sys_exit
, 对于 x86 或使用 syscall
使用 60
对于 64 位或调用 exit
如果您要链接到 C 库,则来自 C 库。
%define SYS_exit 1 ; call number __NR_exit from <asm/unistd_32.h>
mov eax, SYS_exit ; use the NASM macro we defined earlier
xor ebx, ebx ; ebx = 0 exit status
int 80H ; _exit(0)
mov rax, 60 ; SYS_exit aka __NR_exit from asm/unistd_64.h
xor rdi, rdi ; edi = 0 first arg to 64-bit system calls
syscall ; _exit(0)
(在 GAS 中,您实际上可以使用 #include <sys/syscall.h>
或 <asm/unistd.h>
来为您正在组装 .S
的模式获取正确的数字,但 NASM 无法轻松使用 C 预处理器。参见 Polygot include file for nasm/yasm and C提示。)
push 0
call ExitProcess
; pass an int exit_status as appropriate for the calling convention
; push 0 / xor edi,edi / xor ecx,ecx
call exit
(或者对于 32 位 x86 Windows,call _exit
,因为 C 名称前面有一个下划线,这与 x86-64 Windows 不同。POSIX _exit
函数将是 call __exit
,如果 Windows 有的话。)
Windows x64 的调用约定包括调用者必须保留的影子空间,但是 exit
不会返回,所以可以让它踩到返回地址上方的那个空间。此外,调用约定要求在 call exit
之前进行 16 字节堆栈对齐。除了 32 位 Windows,但通常不会因为像 exit()
这样的简单函数而真正崩溃。 .
call exit
(与原始退出系统调用或 libc _exit
不同)将首先刷新 stdio 缓冲区。如果您使用 printf
来自 _start
, 使用 exit
确保在退出之前打印所有输出,即使 stdout 被重定向到一个文件(使 stdout 全缓冲,而不是行缓冲)。
一般建议如果你使用libc函数,你写一个main
函数并与 gcc 链接,因此它会被正常的 CRT 启动函数调用,您可以 ret
到。
另见
定义 main
作为 _start
的东西落入并没有使它变得特别,使用 main
只是令人困惑标签,如果它不像 C main
_start
调用的函数准备在 main
之后退出返回。
关于linux - _start 中 RET 上的 Nasm 段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19760002/
我在玩 GDB 的 rbreak . 时首先注意到它,然后做了一个最小的例子: (gdb) file hello_world.out Reading symbols from hello_world.
在linux _start()中是触发main()函数的汇编函数。 Windows 中有什么?我不确定我的问题是对还是错? 实际上我正在尝试在 Linux 中使用 _start() - 工作正常。但是
我有一个 elf64 可执行文件 foo,我想“手动”加载和启动它并能够从中调用其他函数。我如何将它加载到内存中,然后设置指令指针与它一起运行。 foo 不是一个共享对象库,它是一个可执行文件,具有像
我在 gcc 上编译的 c 代码给出了错误 Cannot find entry symbol _start defaulting to 00000 .谁能告诉我为什么以及如何纠正它? 命令行是 arm
我正在阅读一本描述加载程序如何工作的教科书: When the loader runs, it copies chunks of the executable object file into the
请帮助我使用 arm926ejs cpu 的 gnu 汇编程序。 我尝试构建一个简单的程序(test.S): .global _start _start: mov r0, #2 bx
我尝试将代码不放在主函数中,而是直接放在 _start 中: segment .text global _start _start: push rbp mov rbp,
当我汇编以下汇编代码时,出现错误 Segmentation fault (core dumped) section .text global _start _start: mov eax, 8
我正在 64 位 Linux 中构建没有 glibc 的简单应用程序。但我不知道如何获取参数。 我用谷歌搜索,发现 RDI 是 argc,RSI 是 argv。但它没有用。 当 _start 函数开始
'$' 后跟一个标识符是什么意思? x86 汇编,AT&T 语法。 最佳答案 在 AT&T 语法中 $意味着将后面的内容视为立即常量而不是内存地址。换句话说, movl $_start, %eax 加
在过去的几天里,我一直试图了解当我们执行一个 C 程序时幕后会发生什么。然而,即使在阅读了大量帖子后,我也找不到详细而准确的解释。有人可以帮我吗? 最佳答案 在编译和链接程序时,您通常会为特定用途找到
您好,我制作了一个简单的 hello world C 程序,我正在这样编译它: gcc -c hello.c ld hello.o -lc -o out 我从 ld 收到警告:ld : _start
我在我的应用程序中使用 Asp.Net MVC-4。我创建了一个 Controller ,例如 Person,在这个 Controller 中我有 3 个 Actions,例如 GetName、Get
我正在学习汇编编程。下面是打印“Hello, World!”的简单程序。当程序完美运行时,我收到警告消息,而 loading ld: warning: cannot find entry symbol
我一直在阅读 ELF 规范,但无法弄清楚程序入口点和 _start 地址从何而来。 看起来他们应该在一个非常一致的地方,但我做了一些琐碎的程序,_start 总是在不同的地方。 谁能澄清一下? 最佳答
这个问题在这里已经有了答案: Assembling 32-bit binaries on a 64-bit system (GNU toolchain) (2 个答案) 关闭 6 年前。 我试着在没
我试着写了一个makefile: CC = g++ LD = ld CFLAGS = -Wall -std=c++0x -O3 LDFLAGS = -lgsl -lgslcblas -lpth
我从同事那里收到了我的程序(在 RHEL 5.3 上运行的 qt 应用程序)的回溯,在分析它时我发现了一些我无法解释的东西。如果查看此回溯,您会注意到 main 和 _start 的跟踪。但在此之前,
我写了一个简单的 c 程序,并尝试使用 GDB 来调试程序。我了解在主要功能中使用以下内容: 进入时 push %ebp mov %esp,%ebp 退出时 leave ret 然后我在 _
我已经编译了一个fortran文件并创建了一个目标文件。之后我尝试执行目标文件但出现错误。操作系统是Ubuntu,错误如下: 编译源文件 gfortran -O3 reader.f iotools.c
我是一名优秀的程序员,十分优秀!