下面是用 x86 汇编语言为 Nasm 汇编器编写的“Hello, World”的三个版本。
最小版本 | 这是通常最短的 16 位版本,取决于 DOS 服务打印字符串函数(函数 9)。 |
---|---|
单字符输出 | 稍微扩展一下,也使用 DOS 服务的打印字符功能(功能 2)。 |
长度分隔的字符串 | 此版本依赖于函数 0x40,“写入文件或设备”,根据其长度而不是终止 $(美元符号)输出字符串。 (函数 0x40 是在 DOS 版本 2.0 中添加的,因此并不总是可用。任何仍在使用 DOS 1.x 的人都会被函数 9 卡住。) |
Linux 版本 | Linux 提供了与 DOS 服务(int 0x21)“相似”的内核服务,并且与其他类 Unix 操作系统相似。函数 4 需要一个以长度分隔的字符串。 请注意,Linux 是一个 32 位操作系统,并将进程分为可执行(“文本”)和数据部分。 |
最小尺寸版本
; hello-DOS.asm - single-segment, 16-bit "hello world" program
;
; assemble with "nasm -f bin -o hi.com hello-DOS.asm"
org 0x100 ; .com files always start 256 bytes into the segment
; int 21h is going to want...
mov dx, msg ; the address of or message in dx
mov ah, 9 ; ah=9 - "print string" sub-function
int 0x21 ; call dos services
mov ah, 0x4c ; "terminate program" sub-function
int 0x21 ; call dos services
msg db 'Hello, World!', 0x0d, 0x0a, '$' ; $-terminated message
单个字符输出以及字符串输出
; hello2-DOS.asm - single-segment, 16-bit "hello world" program
;
; This demonstrates single-character output as well as string output
; via DOS services
;
; assemble with "nasm -f bin -o hi.com hello2-DOS.asm"
org 0x100 ; .com files always start 256 bytes into the segment
; int 21h is going to want...
mov dx, msg ; the address of or message in dx
mov ah, 9 ; ah=9 - "print string" sub-function
int 0x21 ; call dos services
mov dl, 0x0d ; put CR into dl
mov ah, 2 ; ah=2 - "print character" sub-function
int 0x21 ; call dos services
mov dl, 0x0a ; put LF into dl
mov ah, 2 ; ah=2 - "print character" sub-function
int 0x21 ; call dos services
mov ah, 0x4c ; "terminate program" sub-function
int 0x21 ; call dos services
msg db 'Hello again, World!$' ; $-terminated message
DOS2 长度分隔输出
; hello3-DOS.asm - single-segment, 16-bit "hello world" program
;
; Use DOS 2.0's service 40 to output a length-delimited string.
;
; assemble with "nasm -f bin -o hi.com hello3-DOS.asm"
org 0x100 ; .com files always start 256 bytes into the segment
; int 21h needs...
mov dx, msg ; message's address in dx
mov cx, len
mov bx, 1 ; Device/handle: standard out (screen)
mov ah, 0x40 ; ah=0x40 - "Write File or Device"
int 0x21 ; call dos services
mov ah, 0x4c ; "terminate program" sub-function
int 0x21 ; call dos services
msg db 'New hello, World!', 0x0d, 0x0a ; message
len equ $ - msg ;msg length
Linux 兼容版本
;Copyright (c) 1999 Konstantin Boldyshev <konst@linuxassembly.org>
;
;"hello, world" in assembly language for Linux
;
;to build an executable:
; nasm -f elf hello.asm
; ld -s -o hello hello.o
section .text
; Export the entry point to the ELF linker or loader. The conventional
; entry point is "_start". Use "ld -e foo" to override the default.
global _start
section .data
msg db 'Hello, world!',0xa ;our dear string
len equ $ - msg ;length of our dear string
section .text
; linker puts the entry point here:
_start:
; Write the string to stdout:
mov edx,len ;message length
mov ecx,msg ;message to write
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
; Exit via the kernel:
mov ebx,0 ;process' exit code
mov eax,1 ;system call number (sys_exit)
int 0x80 ;call kernel - this interrupt won't return