。然后,您需要提供一个_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
另外,您可以直接与ld
所以你也可以链接做到这一点:
nasm -f elf file.asm
ld -melf_i386 -o file file.o
这将产生32位Linux可执行文件,称为file
使用C库/运行
虽然我不认为下列哪项是你预期的,有人可能会觉得有用以下信息内容:
您可以使用GCC并有Ç库通过将_START
重命名为main
可用于您的汇编代码。该ç运行包含一个名为_start
的入口点处理的初始化,然后调用一个名为main
功能。您可以利用库,但main
必须正确设置堆栈帧并正确清理并在完成时返回,因为main
将被视为C函数。该守则将是这个样子:
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
此示例使用两个int 0x80
系统调用写标准输出,并采用Çprintf
做同样的。你可以组装并链接到一个可执行文件名为file
有:
nasm -f elf file.asm
gcc -m32 -o file file.o
'GCC -nostdlib'也确保你打电话给你的入口点'_start'小写。 – Jester