x86 汇编语言中的“Hello, World”

下面是用 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