Liste von Hallo-Welt-Programmen/Assembler
Diese Liste von Hallo-Welt-Programmen von Assemblersprachen enthält kleine Computerprogramme, die auf einfache Weise zeigen, welche Anweisungen für ein vollständiges Programm in einer Programmiersprache benötigt werden.
Zweck
Aufgaben dieser Hallo-Welt-Programme ist, den Text Hallo Welt! in einem einfachen Programm auszugeben. Weitere Programme sind verfügbar:
x86-CPU
DOS (COM-Datei), MASM, TASM
.MODEL Tiny
.CONST
HW DB "Hallo Welt!$"
.CODE
.org 100h
start:
MOV DX, OFFSET DGROUP:HW
MOV AH, 09H
INT 21H
RET
end start
DOS (EXE-Datei), MASM, TASM
.MODEL Small
.STACK 100h
.CONST
HW DB "Hallo Welt!$"
.CODE
start:
MOV AX,@data
MOV DS,AX
MOV DX, OFFSET DGROUP:HW
MOV AH, 09H
INT 21H
MOV AH, 4Ch
INT 21H
end start
DOS, FASM
'''FASM example of writing 16-bit DOS .COM program'''
; Kompilieren: "FASM HELLO.ASM HELLO.COM"
org $100
use16
mov ah,9
mov dx,hello
int $21 ; Textausgabe
mov ah,$4C
int $21 ; Programm beenden
hello db 'Hallo Welt !!!$'
Windows, FASM
; Ausgabe in Messagebox (ohne Titel) mit OK-Button
include 'win32ax.inc'
.code
start:
invoke MessageBox,HWND_DESKTOP,text,"",MB_OK
invoke ExitProcess,0
.end start
.data
text: db "Hallo Welt!",0
Linux
AT&T-Syntax
# Kompilieren mit
# "as -o hallo.o hallo.s; ld -o hallo hallo.o"
.section .data
s: .string "Hallo Welt!\n"
.section .text
.globl _start
_start:
movl $4,%eax # Syscall-ID 4 (= sys_write)
movl $1,%ebx # Ausgabe-Dateideskriptor stdout (= 1)
movl $s,%ecx # Adresse des ersten Zeichens der Zeichenkette
movl $12,%edx # Länge der Zeichenkette (12 Zeichen)
int $0x80 # Softwareinterrupt 0x80, um Syscall (write(1,s,12)) auszuführen
movl $1,%eax # Syscall-ID 1 (= sys_exit)
movl $0,%ebx # Rückgabewert 0 (= alles in Ordnung)
int $0x80 # Softwareinterrupt 0x80 um Syscall (exit(0)) auszuführen
Intel-Syntax
; Befehl zum Assemblen: nasm -felf hello.s
; && ld -o hello hello.o
section data
hello db "Hallo Welt!",0xa
len equ $-hello
section text
global _start
_start:
mov eax, 4 ; write(stdout, hello, len)
mov ebx, 1
mov ecx, hello
mov edx, len
int 80h
mov eax, 1 ; exit(0)
mov ebx, 0
int 80h
x86-CPU, FreeBSD, Intel-Syntax
section .data
hello_world db 'Hallo Welt!', 0x0a
hello_world_len equ $ - hello_world
section .text
align 4
sys:
int 0x80
ret
global _start
_start:
push hello_world_len
push hello_world
push 1
mov eax, 4
call sys
push 0
mov eax, 1
call sys
PowerPC-CPU, Linux
# Kompilieren mit "gcc -nostdlib -s hallo.s"
.section .rodata
.align 2
.s:
.string "Hallo Welt!\n"
.section ".text"
.align 2
.globl _start
_start:
li 0,4 # SYS_write
li 3,1 # fd = 1 (stdout)
lis 4,.s@ha # buf = .s
la 4,.s@l(4)
li 5,12 # len = 12
sc # syscall
li 0,1 # SYS_exit
li 3,0 # returncode = 0
sc # syscall
MMIX, MMIXAL
string BYTE "Hallo Welt!",#a,0 % auszugebende Zeichenkette (#a ist ein Zeilenumbruch,
% 0 schließt die Zeichenkette ab)
Main GETA $255,string % Adresse der Zeichenkette in Register $255 ablegen
TRAP 0,Fputs,StdOut % Zeichenkette, auf die mit Register $255
% verwiesen wird, nach ''StdOut'' ausgeben (Systemaufruf)
TRAP 0,Halt,0 % Prozess beenden
680x0-CPU, Amiga
; Getestet mit ASM-One V1.01
move.l 4.w,a6
lea dosn(pc),a1
jsr -408(a6) ; OldOpenLibrary
move.l d0,a6
lea s(pc),a0
move.l a0,d1
jsr -948(a6) ; PutStr
move.l a6,a1
move.l 4.w,a6
jsr -414(a6) ; CloseLibrary
moveq #0,d0
rts
dosn: dc.b "dos.library",0
s: dc.b "Hallo Welt!",10,0
PA-RISC-CPU, HP-UX
; Kompiliert und getestet mit
; "as hallo.s ; ld hallo.o /usr/ccs/lib/crt0"
; unter HP-UX 11.0 auf einer HP9000/L2000
.LEVEL 1.1
.SPACE $TEXT$
.SUBSPA $LIT$,ACCESS=0x2c
s .STRING "Hallo Welt!\x0a"
.SPACE $TEXT$
.SUBSPA $CODE$,ACCESS=0x2c,CODE_ONLY
.EXPORT _start,ENTRY,PRIV_LEV=3
.EXPORT __errno
.EXPORT __sys_atexit
_start
__errno
__sys_atexit
ldil L'0xC0000000,%r18
ldi 4,%r22 ; SYS_write
ldi 1,%r26 ; fd = stdout
ldil LR's,%r4
ldo RR's(%r4),%r25 ; buf = s
be,l 4(%sr7,%r18) ; Syscall
ldi 12,%r24 ; len = 12 (Branch delay slot)
ldi 1,%r22 ; SYS_exit
be,l 4(%sr7,%r18) ; Syscall
ldi 0,%r26 ; returncode = 0 (Branch delay slot)
SPARC-CPU, Linux
; Kompilieren mit "as -o hallo.o hallo.s; ld -o hallo hallo.o"
.section .data
hello_str:
.asciz "Hallo Welt!\n"
.align 4 ; Speicher muss aligned sein, damit wir später mit ld darauf zugreifen können
hello_str_len:
.word . - hello_str ; Länge der Zeichenkette (12 Zeichen)
.section .text
.global _start
_start:
set 4, %g1 ; Syscall-ID 4 (= __NR_write)
set 1, %o0 ; Ausgabe-Filedeskriptor STDOUT (= 1)
set hello_str, %o1 ; Adresse des ersten Zeichens der Zeichenkette
set hello_str_len, %l0 ; Die Stack-Adresse, an der die Länge der Zeichenkette steht, in local 0 laden
ld [%l0], %o2 ; Den Wert auf den local 0 zeigt in out 2 laden
t 0x110 ; Softwareinterrupt 0x110 um Syscall (write(1,hello_str,hello_str_len))auszuführen
set 1, %g1 ; Syscall-ID 1 (= __NR_exit)
set 0, %o0 ; Rückgabewert 0 (= alles ok)
t 0x110 ; Softwareinterrupt 0x110 um Syscall (exit(0)) auszuführen
Assemblersprache (Jasmin)
; HelloWorld.j
.bytecode 50.0
.source HelloWorld.java
.class public HelloWorld
.super java/lang/Object
.method public <init>()V
.limit stack 1
.limit locals 1
aload_0
invokespecial java/lang/Object/<init>()V
return
.end method
.method public static main([Ljava/lang/String;)V
.limit stack 2
.limit locals 1
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "Hallo Welt!"
invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
return
.end method
MIPS-32 mit erweitertem Befehlssatz
# Emulation mit 'spim -f hw.asm'
.data
helloworld: .asciiz "Hallo Welt!\n" # 'z' in asciiz für Null-terminierter-string
.text
main:
la $a0, helloworld # lade Adresse von helloworld
li $v0, 4 # print_string
syscall
li $v0, 10 # Betriebssystem exit-Routine
syscall
Arm-Armv7l, Linux
.text
.global _start
_start:
/* print */
mov r2, $11
ldr r1, =hw
mov r0, $1
mov r7, $4
svc $0
/* exit */
sub r0, r0, r0
mov r7, $1
svc $0
.data
hw:
.ascii "Hallo Welt\n"
TAS (Telefunken-Assembler-Sprache)
TAS
--- Hallo Welt am TR440 -- HALLO.=SEGM, START HALLO, ALARM CIAO, XBASIS INDIZES, UNTPR 7, VORBES (1,0) -- Einzelheiten zum Programmstart -- INDIZES=ASP 256/G -- Indexspeicher ist Teil des Arbeitsspeichers -- VB616=CIAO/AG, 3/H, TXT/A, 2/H, 0 -- Einzelheiten für SSR 6 16 -- TXT=''*021Hello World'', XBA VB616, SSR 6 16 -- Text ausgeben -- CIAO= SSR 0 12 -- Programmlauf beenden -- ENDE,
- Die Sprache ist weitgehend formatfrei: Informationseinheiten (Befehle und Pseudobefehle) werden durch Kommata oder Kommentare begrenzt.
- Kommentare werden zwischen doppelte Minuszeichen eingeschlossen.
- Ein Kommentar, der mit drei Minuszeichen beginnt, wirkt als Seiten-Überschrift im Assembler-Protokoll.
- Das Betriebssystem benötigt zum Programmstart fünf Angaben: die Start-Adresse, die Alarm-Adresse (Fortsetzung des Programms nach einem Alarm), Anfangswert der Register BXB und BU, Inhalt des freien Arbeitsspeichers.
- Systemdienste werden mit dem SSR-Befehl aufgerufen.
- Konstanten (wie
VB616
) und Variable (wieINDIZES
) werden im Kompilat automatisch getrennt von den Befehlen abgelegt; daher bezeichnetHALLO
den XBA-Befehl (den ersten Befehl in der vorliegenden Quelle).
TASR
--- Hallo Welt am TR440 -- HALLO.=SEGM, R&DRUCKETEXT (''Hello World!'') -- Text ausgeben -- R&ENDE -- Programmlauf beenden -- ENDE,
- TASR bietet einen Rahmen für TAS-Programme, die im Normalmodus ablaufen, und stellt Makros für häufig benötigte Systemdienste zur Verfügung.
- Die 5 Angaben zum Programmstart entfallen, da sie im Rahmenprogramm enthalten sind.
- Alle in diesem Beispiel benötigten Systemdienste können durch Makro-Aufrufe erledigt werden.
IBM-Mainframe-ASSEMBLER
HALLOW CSECT
*
*****************************************************************
* ASSEMBLER-PROGRAMM FUER IBM-MAINFRAME MIT
* STANDARD-REGISTERSICHERUNG, LAUFFAEHIG UNTER
* DEN GAENGIGEN KLASSISCHEN MAINFRAME-BETRIEBSSYSTEMEN
* (ALSO JEDENFALLS Z/OS UND Z/VM UND DEREN VORLAEUFERN)
*****************************************************************
*
STM 14,12,12(13) REGISTER SICHERN
LR 12,15 ENTRYPOINT KOPIEREN NACH REG 12
USING HALLOW,12 BASISADR = ENTRY POINT
LA 2,SAVEAREA NEUE SAVE AREA EINSTELLEN
ST 2,8(13) VORWAERTSVERKETTUNG SAVE AREAS
ST 13,4(2) RUECKWAERTSVERKETTUNG SAVE AREAS
LR 13,2 NEUE SAVE AREA NACH REG 13
*
OPEN (AUSGABE,OUTPUT) DD:SYSPRINT AUFMACHEN
PUT AUSGABE,BUFFER AUSGABE: HALLO WELT!
CLOSE AUSGABE DD:SYSPRINT ZUMACHEN
*
L 13,4(13) ALTE SAVE AREA WIEDER EINSTELLEN
LM 14,12,12(13) REGISTER ZURUECKLADEN
XR 15,15 RETCODE AUF NULL
BR 14 RUECKSPRUNG
*
SAVEAREA DS 18F SAVE AREA
*
AUSGABE DCB DSORG=PS,MACRF=PM,DDNAME=SYSPRINT,RECFM=FBA,LRECL=133
*
BUFFER DC CL133' HALLO WELT!'
*
END HALLOW
Der Programmcode wird in festgelegten Spaltengrenzen erfasst.
- Spalte 1–8 = Namensfeld (Feldbezeichnung oder Sprungziel)
- Stern in Spalte 1 = Kommentarzeile (neuerdings ist es auch möglich, Zeilen komplett leer zu lassen)
- in Spalte 10 beginnend = Befehlscode
- in Spalte 16 beginnend = Operanden, dahinter (nach Leerstelle) optional beliebige Kommentare
- Spalte 72 = Fortsetzung in der nächsten Zeile, wenn hier ein Zeichen ungleich Blank steht (nötig für lange Literale und Makros mit vielen Parametern)
- die Fortsetzung erfolgt ggf. in der nächsten Zeile immer in der Spalte 16
- Spalte 73–80 = Kennung oder lfd. Nummerierung (optional)
Tatsächlich sind die Spaltengrenzen heute etwas flexibler; z. B. gibt es heute Namen mit mehr als 8 Zeichen; dann beginnen die Befehlscodes nicht in Spalte 10, sondern später. Genauso können die Parameter auch nach Spalte 16 beginnen. Die Regeln sind wie folgt:
- Ein Name muss immer in Spalte 1 beginnen, wenn vorhanden
- wenn kein Name vorhanden ist, kommt der Befehlscode frühestens in Spalte 2, ansonsten muss er vom Namensfeld durch mindestens ein Blank abgetrennt sein
- genauso bei den Operanden, sie müssen durch mindestens ein Blank vom Befehlscode abgetrennt sein
- und die Kommentare müssen durch mindestens ein Blank von den Operanden abgetrennt sein
- Blanks in Hochkommas zählen dabei nicht (siehe oben die Blanks im String ' HALLO WELT!' in der mit BUFFER markierten Anweisung)
- wenn ein Befehl keine Operanden braucht, kann man ersatzweise ein einfaches Komma codieren
6502-CPU, C64
;Hello World for 6502 CPU (C64)
;Assembler used: win2c64
LDY #$00 ;init loop counter
L0
LDA L1,Y ;load a byte of the text
BEQ L2 ;if zero -> end
JSR $FFD2 ;call CHROUT
INY ;inc loop counter
JMP L0 ;thanks to paul nicholls
L1
.byte "hello world",0
L2
RTS
8048-CPU, Philips G7000
start
call gfxoff ; switch the graphics off
mov r0,#vdc_char0 ; start char
mov r3,#20h ; x-position
mov r4,#20h ; y-position
mov r2,#0Bh ; length
mov r1,#hellostr & 0FFh ; the string to print
; must be in the same page
loop mov a,r1 ; get pointer
movp a,@a ; get char
mov r5,a ; into to right register
inc r1 ; advance pointer
mov r6,#col_chr_white ; colour
call printchar ; print it
djnz r2,loop ; do it again
call gfxon ; lets see what is written
stop jmp stop ; Thats all
hellostr db 1Dh, 12h, 0Eh, 0Eh, 17h, 0Ch
db 11h, 17h, 13h, 0Eh, 1Ah
Z80-CPU, Amstrad CPC
ld hl,text ; address of text into hl
loop: ld a,(hl) ; load akku by content at address in hl
cp 0 ; compare to zero
ret z ; return if zero
call &bb5a ; otherwise print char in akku
inc hl ; hl=hl+1
jr loop ; relative jump to loop
text: db "Hello World!",0 ; text with 0 as end mark