段错误...在你好世界
Seg fault...on hello world
这段代码非常简单,我的 x86_64 linux 系统出现段错误。这让我很困扰。刚开始接触asm,请耐心等待!
与NASM组装
nasm -f elf64 test.asm
链接到
ld -o test test.o
SECTION .text
GLOBAL _start
_start:
; print name
mov eax,4 ; sys_write
mov ebx,1 ; stdout
mov ecx,name ; start address of name
mov edx,1 ; length
int 80H ; syscall
; exit program
mov eax,1 ; sys_exit
mov ebx,0 ; success
int 80H ; sys_call
SECTION .data
name DB 'R'
我的机器:Gentoo x86_64 nomultilib!我在没有 IA32 仿真的情况下编译了自己的内核。我应该声明我的系统是 64 位系统。这会归因于我收到的错误吗?
$ uname -a
Linux rcepeda 4.4.1-2-ARCH #1 SMP PREEMPT Wed Feb 3 13:12:33 UTC 2016 x86_64 GNU/Linux
解决方案
使用 64 位寄存器和 64 位 linux 调度程序
使用系统调用(不是 int 80H)。
谢谢内特和迈克尔
SECTION .text
GLOBAL _start
_start:
; print name
mov rax,1 ; sys_write
mov rdi,1 ; stdout
mov rsi,name ; start address of name
mov rdx,7 ; length
syscall
; exit program
mov rax,60 ; sys_exit
mov rdi,0 ; success
syscall
SECTION .data
name DB "Rafael",10
.
rafael@rcepeda ~/asm $ ./a.out
Rafael
您 运行 处于 64 位模式,但这是 32 位代码。如果您想要 64 位代码,则必须重写它。
您应该使用 64 位寄存器 rax, rbx
,等等。在 64 位 Linux 中,系统调用不再使用 int 80h
,而是使用新的 syscall
指令。有关示例,请参见 http://cs.lmu.edu/~ray/notes/linuxsyscalls/(请注意,这使用 AT&T assembler 语法而不是 Intel)。
或者,您可以保持代码不变,assemble 和 link 在 32 位模式下,使用 nasm -f elf32
和 ld -m elf_i386
。但是你正在学习(相对)过时的技术。 (编辑:实际上,您的特定系统似乎未启用 32 位兼容性,因此这对您根本不起作用。)
这段代码非常简单,我的 x86_64 linux 系统出现段错误。这让我很困扰。刚开始接触asm,请耐心等待!
与NASM组装
nasm -f elf64 test.asm
链接到
ld -o test test.o
SECTION .text
GLOBAL _start
_start:
; print name
mov eax,4 ; sys_write
mov ebx,1 ; stdout
mov ecx,name ; start address of name
mov edx,1 ; length
int 80H ; syscall
; exit program
mov eax,1 ; sys_exit
mov ebx,0 ; success
int 80H ; sys_call
SECTION .data
name DB 'R'
我的机器:Gentoo x86_64 nomultilib!我在没有 IA32 仿真的情况下编译了自己的内核。我应该声明我的系统是 64 位系统。这会归因于我收到的错误吗?
$ uname -a
Linux rcepeda 4.4.1-2-ARCH #1 SMP PREEMPT Wed Feb 3 13:12:33 UTC 2016 x86_64 GNU/Linux
解决方案
使用 64 位寄存器和 64 位 linux 调度程序
使用系统调用(不是 int 80H)。
谢谢内特和迈克尔
SECTION .text
GLOBAL _start
_start:
; print name
mov rax,1 ; sys_write
mov rdi,1 ; stdout
mov rsi,name ; start address of name
mov rdx,7 ; length
syscall
; exit program
mov rax,60 ; sys_exit
mov rdi,0 ; success
syscall
SECTION .data
name DB "Rafael",10
.
rafael@rcepeda ~/asm $ ./a.out
Rafael
您 运行 处于 64 位模式,但这是 32 位代码。如果您想要 64 位代码,则必须重写它。
您应该使用 64 位寄存器 rax, rbx
,等等。在 64 位 Linux 中,系统调用不再使用 int 80h
,而是使用新的 syscall
指令。有关示例,请参见 http://cs.lmu.edu/~ray/notes/linuxsyscalls/(请注意,这使用 AT&T assembler 语法而不是 Intel)。
或者,您可以保持代码不变,assemble 和 link 在 32 位模式下,使用 nasm -f elf32
和 ld -m elf_i386
。但是你正在学习(相对)过时的技术。 (编辑:实际上,您的特定系统似乎未启用 32 位兼容性,因此这对您根本不起作用。)