【发布时间】:2016-06-03 10:18:35
【问题描述】:
这段代码非常简单,我的 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
【问题讨论】:
-
为我工作。你的
uname -a是什么? -
@MichaelPetch:它打印
R而不是Hello world,仅此而已。但除此之外,它是真正的代码。 -
@NateEldredge 我知道这是一个完整的例子,但用户可能没有给我们他的确切代码。由于他的标题表明不同的输出可能表明代码段错误可能不是显示的代码。因此,我要求澄清。除非此代码在较低的 4gb 地址空间之外运行,否则即使它是使用 32 位
int 0x80机制的 64 位应用程序,它也应该可以工作。 -
我也和@YOU 在一起。我很好奇
uname -a会返回什么。在您的问题中表明这一点会很有帮助 -
如果您使用 IA32 仿真支持构建内核,您的程序可能会运行。大多数 Linux 发行版都使用其 64 位内核启用 IA32 仿真,因此可以向后兼容旧的 32 位用户代码。
标签: linux assembly x86-64 system-calls