64 位 Windows 子系统 Linux 上的 32 位系统调用或可执行文件?或者一个工作的 64 位 Hello World? [英] 32-bit system calls or executables on 64bit Windows Subsystem For Linux? Or a working 64-bit Hello World?

查看:44
本文介绍了64 位 Windows 子系统 Linux 上的 32 位系统调用或可执行文件?或者一个工作的 64 位 Hello World?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图学习 NASM 并从一个 helloworld 程序开始.本教程本身是 Linux 上的 32 位 NASM.

I was trying to learn NASM and started from a helloworld program. The tutorial itself is 32 bit NASM on Linux.

我复制并粘贴创建的 helloworld.asm(使用 int 0x80 32 位系统调用)并输入命令...

I copy and paste the created helloworld.asm (using int 0x80 32-bit system calls) and input the commands...

nasm -f elf helloworld.asm
ld -m elf_i386 helloworld.o -o helloworld

这两个看起来不错,但是运行 ./helloworld 会产生

these two looks good but running ./helloworld produces

-bash: ./helloworld: 无法执行二进制文件:Exec 格式错误

-bash: ./helloworld: cannot execute binary file: Exec format error

然后我搜索了这个错误并喜欢这个 SO 发布.我输入了那个答案的命令:

Then I searched this error and fond this SO posting. I entered the commands of that answer:

sudo apt-get install gcc-multilib g++-multilib

在那之后,我安装了这个:

after that, I installed this:

nasm -f elf64 helloworld.asm -o helloworld.o
ld -o helloworld helloworld.o -m elf_x86_64

都来自那个答案并且没有发生错误.
然后我执行 ./helloworld 并得到以下错误:

both came from that answer and no error occurred.
Then I executed ./helloworld and got the following error:

分段错误(核心转储)

好的,然后我也搜索了这个新错误.(编者注:如果在 64 位代码中使用 32 位 int 0x80 Linux ABI 会发生什么? 解释了确切原因:WSL 1 不支持 32 位 int 0x8064 位代码中的系统调用,这通常不是一个好主意).

Okay, then I searched this new error as well. (Editor's note: What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code? explains the exact reason: WSL 1 doesn't support 32-bit int 0x80 system calls in 64-bit code, and it's generally not a good idea).

大多数答案都没有给出确切的解决方案.我唯一得到的就是这个.看起来我需要修改 NASM 代码,他说

Most of the answer doesn't give an exact solution. The only one I got is this. It looks like I need to modify the NASM code, he says

64bit sys_exit = 60 32bit sys_exit = 1
64bit sys_write = 1 32bit sys_write = 4

32 bit sys_exit:
mov     ebx, ERR_CODE
mov     eax, sys_exit  ; 1
int     80h
64 bit sys_exit:
mov     rdi, ERR_CODE
mov     rax, sys_exit  ; 60
syscall

所以我修改了原来的代码,变成了这样:
原代码:

so I modified the original code and it became this:
The original code:

; Hello World Program - asmtutor.com
; Compile with: nasm -f elf helloworld.asm
; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 helloworld.o -o helloworld
; Run with: ./helloworld
 
SECTION .data
msg     db      'Hello World!', 0Ah
 
SECTION .text
global  _start
 
_start:
 
    mov     edx, 13
    mov     ecx, msg
    mov     ebx, 1
    mov     eax, 4
    int     80h
 
    mov     ebx, 0      ; return 0 status on exit - 'No Errors'
    mov     eax, 1      ; invoke SYS_EXIT (kernel opcode 1)
    int     80h

以及修改后的代码:

; Hello World Program - asmtutor.com
; Compile with: nasm -f elf helloworld.asm
; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 helloworld.o -o helloworld
; Run with: ./helloworld
 
SECTION .data
msg     db      'Hello World!', 0Ah
 
SECTION .text
global  _start
 
_start:
 
    mov     edx, 13
    mov     ecx, msg
    mov     rdi, 1
    mov     rax, 1      ; SYS_write 64-bit ABI
    syscall
 
    mov     rdi, 0      ; return 0 status on exit - 'No Errors'
    mov     rax, 60     ; invoke SYS_exit (kernel opcode 1)
    syscall

我修改代码后,再次输入上面的命令:

After I modified the code, I input the command above again:

nasm -f elf64 helloworld.asm -o helloworld.o
ld -o helloworld helloworld.o -m elf_x86_64
./helloworld

好.没有错误了.但是也没有输出,应该是helloworld".

Good. There is no error anymore. But there is not output either, which should be "helloworld".

然后我回到首先尝试教程中给出的命令,从在 64 位模式下工作的源代码构建一个 32 位可执行文件:

nasm -f elf helloworld.asm

其结果是:

helloworld.asm:16: 错误:32 位模式不支持指令
helloworld.asm:17: 错误:32 位模式不支持指令
helloworld.asm:20: 错误:32 位模式不支持指令
helloworld.asm:21: 错误:32 位模式不支持指令

helloworld.asm:16: error: instruction not supported in 32-bit mode
helloworld.asm:17: error: instruction not supported in 32-bit mode
helloworld.asm:20: error: instruction not supported in 32-bit mode
helloworld.asm:21: error: instruction not supported in 32-bit mode

然后我再次搜索这个错误,但我找不到解决方案.
我的机器是 64 位 Linux Ubuntu,作为 64 位 Windows 10 中的 Windows-Subsystem-For-Linux.

Then I searched this error again, but I cannot find a solution.
My machine is a 64bit Linux Ubuntu as a Windows-Subsystem-For-Linux in 64bit Windows 10.

如何正确运行这个helloworld程序?
这是否意味着 32 位 Linux NASM 教程/程序就不能在 64 位 Linux 上运行?
还是 64 位 Windows10?
还是在 Windows-Subsystem-For-Linux 中?

How to run this helloworld program correctly?
Does this mean that a 32bit Linux NASM tutorial/program just cannot run on a 64bit Linux?
Or a 64-bit Windows10?
Or in a Windows-Subsystem-For-Linux?

是什么问题,为什么会出现这么多错误?
我应该如何避免将来发生类似的潜在错误?

What is the problem, and why do occur so many errors?
How should I avoid similar potential errors in the future?

推荐答案

快速修复
你要编译 32 位还是 64 位?
您的程序将通过 rsi

; Hello World Program - asmtutor.com
; Compile with: nasm -f elf helloworld.asm
; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 helloworld.o -o helloworld
; Run with: ./helloworld

SECTION .data
msg     db      'Hello World!',0Ah

SECTION .text
global  _start

_start:

    mov     edx, 13
    mov     rsi, msg
    mov     rdi, 1
    mov     rax, 1
    syscall

    mov     rdi, 0      ; return 0 status on exit - 'No Errors'
    mov     rax, 60      ; invoke SYS_EXIT (kernel opcode 1)
    syscall

使用 nasm 和 ld 编译 64 位程序

Compile your program for 64 bits using nasm and ld

nasm -f elf64 helloworld.asm -o helloworld.o  
ld helloworld.o -o helloworld.elf  

这篇关于64 位 Windows 子系统 Linux 上的 32 位系统调用或可执行文件?或者一个工作的 64 位 Hello World?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆