问题描述
限时送ChatGPT账号..我试图学习 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 0x80
64 位代码中的系统调用,这通常不是一个好主意).
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
; 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
; 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
; 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屋!
更多推荐
[db:关键词]
发布评论