linux汇编“;collect2:ld返回1退出状态“;
我在一个在线编码网站上输入了源代码 但我在源代码下面发现了错误 我想我省略了“main” 自从我学会了英特尔assmbly,我不知道如何修复它 你能帮我吗 谢谢你提前帮助我linux汇编“;collect2:ld返回1退出状态“;,linux,gcc,assembly,x86,linker-errors,Linux,Gcc,Assembly,X86,Linker Errors,我在一个在线编码网站上输入了源代码 但我在源代码下面发现了错误 我想我省略了“main” 自从我学会了英特尔assmbly,我不知道如何修复它 你能帮我吗 谢谢你提前帮助我 SECTION .DATA hello: db 'Hello world!',10 helloLen: equ $-hello SECTION .TEXT GLOBAL _START _START: ; Write 'Hello world!' to the screen mov e
SECTION .DATA
hello: db 'Hello world!',10
helloLen: equ $-hello
SECTION .TEXT
GLOBAL _START
_START:
; Write 'Hello world!' to the screen
mov eax,4 ; 'write' system call
mov ebx,1 ; file descriptor 1 = screen
mov ecx,hello ; string to write
mov edx,helloLen ; length of string to write
int 80h ; call the kernel
; Terminate program
mov eax,1 ; 'exit' system call
mov ebx,0 ; exit with error code 0
int 80h ; call the kernel
/usr/lib/gcc/i686 linux gnu/4.6/../../../..//i386 linux gnu/crt1.o:在函数\u start'中:
(.text+0x18):未定义对
main'的引用
collect2:ld返回了1个退出状态如果您只是将GCC用作链接器,而不关心C运行时,那么您可以通过将-nostlib
传递给GCC来排除它(正如Jester指出的)。然后需要提供一个\u start
符号,使代码看起来像:
SECTION .DATA
hello: db 'Hello world!',10
helloLen: equ $-hello
SECTION .TEXT
GLOBAL _start
_start:
; Write 'Hello world!' to the screen
mov eax,4 ; 'write' system call
mov ebx,1 ; file descriptor 1 = screen
mov ecx,hello ; string to write
mov edx,helloLen ; length of string to write
int 80h ; call the kernel
; Terminate program
mov eax,1 ; 'exit' system call
mov ebx,0 ; exit with error code 0
int 80h ; call the kernel
您可以这样组装和链接它:
nasm -f elf file.asm
gcc -m32 -nostdlib -o file file.o
EXTERN printf ; Tell the assembler printf is provided outside our file
SECTION .DATA
hello: db 'Hello world!',10,0 ; Null terminate for printf
helloLen: equ $-hello-1 ; Exclude null by reducing len by 1
SECTION .TEXT
GLOBAL main
; main is now a C function
main:
push ebp ; Setup stack frame
mov ebp, esp
push ebx ; We need to preserve EBX (C Calling convention)
; Write 'Hello world!' to the screen
mov eax,4 ; 'write' system call
mov ebx,1 ; file descriptor 1 = screen
mov ecx,hello ; string to write
mov edx,helloLen ; length of string to write
int 80h ; call the kernel
; Write 'Hello World!' with C printf
push hello ; push the address of string to print
call printf ; call printf in C library
add esp, 4 ; Restore stack pointer
; push hello pushed 4 bytes on stack
mov eax, 0x0 ; Return value of 0
pop ebx ; Restore EBX
leave
ret ; Return to C runtime which will cleanup and exit
或者,您可以直接链接到ld
,也可以这样做:
nasm -f elf file.asm
ld -melf_i386 -o file file.o
这将生成一个名为file
32位Linux可执行文件
使用C库/运行时
虽然我不认为以下是您的意图,但有些人可能会发现以下信息很有用:
通过将\u START
重命名为main
,可以使用GCC并使C库可用于汇编代码。C运行时包含一个名为\u start
的入口点,该入口点处理初始化,然后调用名为main
的函数。您可以利用C库,但main
必须正确设置堆栈框架,并正确清理堆栈框架,完成后返回,因为main
将被视为C函数。代码如下所示:
nasm -f elf file.asm
gcc -m32 -nostdlib -o file file.o
EXTERN printf ; Tell the assembler printf is provided outside our file
SECTION .DATA
hello: db 'Hello world!',10,0 ; Null terminate for printf
helloLen: equ $-hello-1 ; Exclude null by reducing len by 1
SECTION .TEXT
GLOBAL main
; main is now a C function
main:
push ebp ; Setup stack frame
mov ebp, esp
push ebx ; We need to preserve EBX (C Calling convention)
; Write 'Hello world!' to the screen
mov eax,4 ; 'write' system call
mov ebx,1 ; file descriptor 1 = screen
mov ecx,hello ; string to write
mov edx,helloLen ; length of string to write
int 80h ; call the kernel
; Write 'Hello World!' with C printf
push hello ; push the address of string to print
call printf ; call printf in C library
add esp, 4 ; Restore stack pointer
; push hello pushed 4 bytes on stack
mov eax, 0x0 ; Return value of 0
pop ebx ; Restore EBX
leave
ret ; Return to C runtime which will cleanup and exit
本例使用int0x80
系统调用写入标准输出,并使用Cprintf
执行相同的操作。您可以使用以下工具组合并链接到名为文件的可执行文件:
nasm -f elf file.asm
gcc -m32 -o file file.o
gcc-nostlib
还请确保您以小写形式调用您的入口点\u start
。非常感谢。第二本在网站上很有用。你能推荐一本学习linux汇编的书吗?我读过基普·R·欧文。但它是针对基于英特尔的计算机的。您使用的代码是针对与英特尔兼容的计算机的。也许你的意思是Kip R Irvine材料是针对Windows的,而你正在寻找Linux材料。我实际上没有任何关于这个问题的书籍,所以我不能提出建议,但是你可能想把这个在线教程作为一个起点: