尝试在 Ubuntu 上的 NASM 上运行 .asm 文件时出错
Posted
技术标签:
【中文标题】尝试在 Ubuntu 上的 NASM 上运行 .asm 文件时出错【英文标题】:Error when trying to run .asm file on NASM on Ubuntu 【发布时间】:2011-05-14 05:26:06 【问题描述】:我正在使用 ubuntu 64 位并尝试在 NASM 上运行 .asm 文件。但是当我尝试运行以下代码时它会返回此错误。我试图做的是通过从源代码编译(或组装)目标文件来构建可执行文件
$ nasm -f elf hello.asm
,然后在创建文件后,hello.o
通过调用链接器从目标文件生成可执行文件本身
$ ld -s -o hello hello.o
这将最终构建 hello 可执行文件。
我正在关注这个教程http://www.faqs.org/docs/Linux-HOWTO/Assembly-HOWTO.html
错误:
输入文件 `hello.o' 的 i386 架构与 i386:x86-64 输出不兼容
代码:
section .data ;section declaration
msg db "Hello, world!",0xa ;our dear string
len equ $ - msg ;length of our dear string
section .text ;section declaration
;we must export the entry point to the ELF linker or
global _start ;loader. They conventionally recognize _start as their
;entry point. Use ld -e foo to override the default.
_start:
;write our string to stdout
mov edx,len ;third argument: message length
mov ecx,msg ;second argument: pointer to message to write
mov ebx,1 ;first argument: file handle (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
;and exit
mov ebx,0 ;first syscall argument: exit code
mov eax,1 ;system call number (sys_exit)
int 0x80 ;call kernel
【问题讨论】:
【参考方案1】:如何在 Ubuntu 64 位上编译、链接和运行 nasm 应用程序。
安装 nasm:
sudo apt-get install nasm
用文件名hello.asm
保存文件:
section .data
hello: db 'Hello world!',10 ; 'Hello world!' plus a linefeed character
helloLen: equ $-hello ; Length of the 'Hello world!' string
; (I'll explain soon)
section .text
global _start
_start:
mov eax,4 ; The system call for write (sys_write)
mov ebx,1 ; File descriptor 1 - standard output
mov ecx,hello ; Put the offset of hello in ecx
mov edx,helloLen ; helloLen is a constant, so we don't need to say
; mov edx,[helloLen] to get it's actual value
int 80h ; Call the kernel
mov eax,1 ; The system call for exit (sys_exit)
mov ebx,0 ; Exit with return code of 0 (no error)
int 80h
编译:
nasm -f elf64 hello.asm
链接:
ld -s -o hello hello.o
运行它
el@apollo:~$ ./hello
Hello world!
有效!现在怎么办? 请求您最喜欢的编译器生成汇编代码,它通常会被传递以转换为机器代码。谷歌搜索:“将php/java/python/c++程序转换为程序集”
观点:当今所有人都在试图为公众拆除并摆脱通用计算,因此我们必须教新学生如何构建通用计算的概念图灵机从核心原理,到裸机,最后是汇编程序和编程语言。
学习汇编对编程有何帮助? 99% 的计算机程序比优化后的速度要慢 10 到 100 倍,这仅仅是因为程序员不知道他们最喜欢的高级编译器或解释器对他们施加了哪些延迟。
全面了解此处的完整堆栈意味着您可以强制您的程序拥有令人垂涎的特性,即只需几纳秒即可完成手头的工作。时间==金钱。因此,了解如何避免任何需要超过几纳秒才能完成的事情可以节省时间,从而节省金钱。
https://softwareengineering.stackexchange.com/questions/156722/how-does-learning-assembly-aid-in-programming
【讨论】:
谢谢,我使用 Sasm 作为 ide,它在链接器上有 -m64 之类的选项,还有 -g 这给我带来了麻烦......顺便说一句,答案很干净......跨度> 【参考方案2】:您需要告诉链接器生成 i386 输出文件,因为您正在编写 i386 程序集:
ld -m elf_i386 -s -o hello hello.o
【讨论】:
当我使用这个命令时,它返回同样的错误:ld: i386:x86-64 architecture of input file `hello.o' is incompatible with i386 output @psyhclo:不,那是不是同样的错误,那是相反的错误,因为你也告诉nasm
创建x86-64输出。做一个或另一个,而不是两个! (我强烈建议创建i386
输出,这意味着像您最初那样调用nasm
,并以这种方式调用ld
,因为您实际上是在编写i386 汇编程序而不是x86-64)。【参考方案3】:
这看起来可能是nasm
产生的内容与ld
试图制作的内容之间的简单不匹配:
i386 architecture of input file 'hello.o' is incompatible with i386:x86-64 output
换句话说,nasm
已经生成了一个 32 位目标文件 hello.o
并且 ld
想要使用它并生成一个 64 位可执行文件。
nasm -hf
命令应该为您提供可用的输出格式:
valid output formats for -f are (`*' denotes default):
* bin flat-form binary files (e.g. DOS .COM, .SYS)
ith Intel hex
srec Motorola S-records
aout Linux a.out object files
aoutb NetBSD/FreeBSD a.out object files
coff COFF (i386) object files (e.g. DJGPP for DOS)
elf32 ELF32 (i386) object files (e.g. Linux)
elf ELF (short name for ELF32)
elf64 ELF64 (x86_64) object files (e.g. Linux)
as86 Linux as86 (bin86 version 0.3) object files
obj MS-DOS 16-bit/32-bit OMF object files
win32 Microsoft Win32 (i386) object files
win64 Microsoft Win64 (x86-64) object files
rdf Relocatable Dynamic Object File Format v2.0
ieee IEEE-695 (LADsoft variant) object file format
macho32 NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (i386) object files
macho MACHO (short name for MACHO32)
macho64 NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) object files
dbg Trace of all info passed to output stage
我看到您的链接教程要求您运行:
nasm -f elf hello.asm
尝试使用:
nasm -f elf64 hello.asm
相反,您可能会发现ld
不再抱怨输入文件。
【讨论】:
这不是真正正确的方法,因为 OP 正在编写的程序集也必须修改(例如,%rax
、%rbx
等的高 32 位需要在系统调用之前被清除)。
是的,@caf,你可能是对的。我自己,我更喜欢更改代码方法,因为我正在运行 64 位,但我可以看到在某些情况下创建 32 位可执行文件会更好。您的答案可能提供了让这些东西正常工作的最小努力版本,因此这可能是学习教程的最佳方式。所以+1。
我按照@paxdiablo 说的做了,效果很好。那么这是正确的做法吗?因为对我来说工作得很好!谢谢。
谢谢,我使用 Sasm 作为 ide,它在链接器上有 -m64 之类的选项,还有 -g 这给我带来了麻烦......顺便说一句,答案很干净......跨度>
以上是关于尝试在 Ubuntu 上的 NASM 上运行 .asm 文件时出错的主要内容,如果未能解决你的问题,请参考以下文章
我正在尝试运行 CUDA 示例,但我在 Ubuntu 16.04 LTS 上遇到了 openGL (libGLEW.a) 问题
错误记录Ubuntu 编译 ffmpeg 报错 ( nasm/yasm not found or too old. Use --disable-x86asm for a crippled bu )