Windows上的Ubuntu上的Bash上的汇编编译可执行文件不产生输出 [英] Assembly compiled executable on Bash on Ubuntu on Windows doesn't produce output
问题描述
我一直在看汇编教程,我正在尝试运行一个hello world程序.我正在Windows的Ubuntu上使用Bash.
I've been looking at a tutorial for assembly, and I'm trying to get a hello world program to run. I am using Bash on Ubuntu on Windows.
这里是程序集:
section .text
global _start ;must be declared for linker (ld)
_start: ;tells linker entry point
mov edx,len ;message length
mov ecx,msg ;message to write
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
mov eax,1 ;system call number (sys_exit)
int 0x80 ;call kernel
section .data
msg db 'Hello, world!', 0xa ;string to be printed
len equ $ - msg ;length of the string
我正在使用以下命令创建可执行文件:
I am using these commands to create the executable:
nasm -f elf64 hello.asm -o hello.o
ld -o hello hello.o -m elf_x86_64
然后我使用以下命令运行它:
And I run it using:
./hello
然后该程序似乎没有分段错误或错误运行,但没有任何输出.
The program then seems to run without a segmentation fault or error, but it produces no output.
我不知道为什么代码不会产生输出,但是我想知道Windows上在Ubuntu上使用Bash是否与此有关?为什么它不产生输出,我该如何解决?
I can't figure out why the code won't produce an output, but I wonder if using Bash on Ubuntu on Windows has anything to do with it? Why doesn't it produce output and how can I fix it?
推荐答案
问题出在Windows的Ubuntu(Linux的Windows子系统)上.它仅支持64位syscall
接口和 不 32-位x86 int 0x80
系统调用机制.
The issue is with Ubuntu for Windows (Windows Subsystem for Linux). It only supports the 64-bit syscall
interface and not the 32-bit x86 int 0x80
system call mechanism.
除了无法在64位二进制文件中使用int 0x80
(32位兼容性)之外,Windows上的Ubuntu(WSL)
Besides not being able to use int 0x80
(32-bit compatibility) in 64-bit binaries, Ubuntu on Windows (WSL) doesn't support running 32-bit executables either.
您需要从使用int 0x80
转换为 syscall
.不难syscall
使用一组不同的寄存器,并且系统调用号与其32位对应号不同. Ryan Chapman的博客提供有关syscall
界面,系统调用及其参数的信息. Sys_write
和Sys_exit
的定义方式如下:
You need to convert from using int 0x80
to syscall
. It's not difficult. A different set of registers are used for a syscall
and the system call numbers are different from their 32-bit counterparts. Ryan Chapman's blog has information on the syscall
interface, the system calls, and their parameters. Sys_write
and Sys_exit
are defined this way:
%rax System call %rdi %rsi %rdx %r10 %r8 %r9
----------------------------------------------------------------------------------
0 sys_read unsigned int fd char *buf size_t count
1 sys_write unsigned int fd const char *buf size_t count
60 sys_exit int error_code
使用syscall
还可掩盖 RCX 和 R11 寄存器.它们被认为是易变的.不要依赖syscall
之后的相同值.
Using syscall
also clobbers RCX and the R11 registers. They are considered volatile. Don't rely on them being the same value after the syscall
.
您的代码可以修改为:
section .text
global _start ;must be declared for linker (ld)
_start: ;tells linker entry point
mov edx,len ;message length
mov rsi,msg ;message to write
mov edi,1 ;file descriptor (stdout)
mov eax,edi ;system call number (sys_write)
syscall ;call kernel
xor edi, edi ;Return value = 0
mov eax,60 ;system call number (sys_exit)
syscall ;call kernel
section .data
msg db 'Hello, world!', 0xa ;string to be printed
len equ $ - msg ;length of the string
注意:如果指令的目标寄存器是32位(如 EAX , EBX , EDI , ESI 等),处理器零将结果扩展到高32位的64位寄存器. mov edi,1
与mov rdi,1
具有相同的作用.
Note: in 64-bit code if the destination register of an instruction is 32-bit (like EAX, EBX, EDI, ESI etc) the processor zero extends the result into the upper 32-bits of the 64-bit register. mov edi,1
has the same effect as mov rdi,1
.
此答案不是编写64位代码的入门书,仅关于使用syscall
接口.如果您对编写调用 C 库并符合64位System V ABI的代码的细微差别感兴趣,可以使用一些合理的教程来入门,例如
This answer isn't a primer on writing 64-bit code, only about using the syscall
interface. If you are interested in the nuances of writing code that calls the C library, and conforms to the 64-bit System V ABI there are reasonable tutorials to get you started like Ray Toal's NASM tutorial. He discusses stack alignment, the red zone, register usage, and a basic overview of the 64-bit System V calling convention.
这篇关于Windows上的Ubuntu上的Bash上的汇编编译可执行文件不产生输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!