Hello world (with proper exit), in 32 and 64 bit implementations.
This commit is contained in:
parent
b5503dad30
commit
4a7fa5a427
|
@ -0,0 +1,4 @@
|
|||
*.o
|
||||
*~
|
||||
\#*
|
||||
.\#*
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
|
||||
hello32:
|
||||
nasm -f elf hello32.s
|
||||
ld -m elf_i386 -o hello32 hello32.o
|
||||
|
||||
hello64:
|
||||
nasm -f elf64 hello64.s
|
||||
ld -o hello64 hello64.o
|
||||
|
||||
clean:
|
||||
rm -f hello32 hello64 *.o
|
|
@ -0,0 +1,30 @@
|
|||
;; Hello World Program #1
|
||||
;; Compile with: nasm -f elf32 hello.s
|
||||
;; Link with: ld -m elf_i386 -o hello hello.o
|
||||
;; Run with: ./hello
|
||||
|
||||
;; sys/syscall.h
|
||||
%define SYS_write 4
|
||||
%define SYS_exit 1
|
||||
|
||||
;; unistd.h
|
||||
%define STDOUT 1
|
||||
|
||||
section .data
|
||||
msg db "Hello You Beautiful Human", 0Ah
|
||||
|
||||
section .text
|
||||
global _start
|
||||
|
||||
_start:
|
||||
mov edx, 26d ; Length of the message
|
||||
mov ecx, msg ; Address of the message
|
||||
mov ebx, STDOUT ; using STDOUT (see definition above)
|
||||
mov eax, SYS_write ; Using WRITE in 32-bit mode?
|
||||
int 80h
|
||||
|
||||
mov ebx, 0
|
||||
mov eax, SYS_exit
|
||||
int 80h
|
||||
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
;; Hello World Program #1
|
||||
;; Compile with: nasm -f elf32 hello.s
|
||||
;; Link with: ld -m elf_i386 -o hello hello.o
|
||||
;; Run with: ./hello
|
||||
|
||||
;; sys/syscall.h
|
||||
%define SYS_write 1
|
||||
%define SYS_exit 60
|
||||
|
||||
;; unistd.h
|
||||
%define STDOUT 1
|
||||
|
||||
section .data
|
||||
msg db "Hello You Beautiful Human", 0Ah
|
||||
|
||||
section .text
|
||||
global _start
|
||||
|
||||
_start:
|
||||
mov rdx, 26d ; Length of the message
|
||||
mov rsi, msg ; Address of the message
|
||||
mov rdi, STDOUT ; using STDOUT (see definition above)
|
||||
mov rax, SYS_write ; Using WRITE in 32-bit mode?
|
||||
syscall
|
||||
|
||||
mov rdi, 0
|
||||
mov rax, SYS_exit
|
||||
syscall
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
;; Pure assembly, library-free Linux threading demo
|
||||
bits 32
|
||||
global _start
|
||||
|
||||
;; sys/syscall.h
|
||||
%define SYS_write 1
|
||||
%define SYS_exit 60
|
||||
|
||||
;; unistd.h
|
||||
%define STDOUT 1
|
||||
|
||||
section .data
|
||||
hello: db `Goodbye\10`
|
||||
|
||||
section .text
|
||||
_start:
|
||||
mov eax, 9234d ; The number we're processing; this is
|
||||
; the dividend target for the div operation
|
||||
xor esi, esi ; fast zero
|
||||
.loop:
|
||||
mov edx, 0d ; counter
|
||||
mov ebx, 10d ; divisor
|
||||
div ebx
|
||||
add edx, 48d ; the remainder, plus the ASCII for '0'
|
||||
; the quotient is put into eax
|
||||
push edx ; onto the stack
|
||||
inc esi ; Increment counter
|
||||
cmp eax, 0d ; if EAX is zero, we're done.
|
||||
jz .print
|
||||
jmp .loop
|
||||
.print:
|
||||
cmp esi, 0d ; if counter is zero, we're done.
|
||||
jz .exit
|
||||
dec esi ; decrement the counter
|
||||
pop ecx ; copy the address of the stack pointer to edx
|
||||
mov edx, 1 ; One byte
|
||||
mov ebx, STDOUT ; To stdout
|
||||
int SYS_write ; Do it!
|
||||
jmp .print
|
||||
|
||||
.exit:
|
||||
mov esi, hello ; move the contents of the stack pointer into ECX
|
||||
mov ecx, 6 ; One byte
|
||||
mov ebx, STDOUT ; To stdout
|
||||
mov eax, SYS_write ; Do it!
|
||||
mov edi, 0 ; Success!
|
||||
mov eax, SYS_exit ; Do it!
|
||||
syscall
|
|
@ -0,0 +1,25 @@
|
|||
;; Pure assembly, library-free Linux threading demo
|
||||
bits 32
|
||||
global _start
|
||||
|
||||
;; sys/syscall.h
|
||||
%define SYS_write 1
|
||||
%define SYS_exit 60
|
||||
|
||||
;; unistd.h
|
||||
%define STDOUT 1
|
||||
|
||||
section .data
|
||||
hello: db `Goodbye\n`
|
||||
|
||||
section .text
|
||||
_start:
|
||||
mov esi, hello
|
||||
mov edx, 8d
|
||||
mov edi, STDOUT
|
||||
mov eax, SYS_write
|
||||
syscall
|
||||
|
||||
mov edi, 0 ; Success!
|
||||
mov eax, SYS_exit ; Do it!
|
||||
syscall
|
|
@ -0,0 +1,108 @@
|
|||
;; Pure assembly, library-free Linux threading demo
|
||||
bits 64
|
||||
global _start
|
||||
|
||||
;; sys/syscall.h
|
||||
%define SYS_write 1
|
||||
%define SYS_mmap 9
|
||||
%define SYS_clone 56
|
||||
%define SYS_exit 60
|
||||
|
||||
;; unistd.h
|
||||
%define STDIN 0
|
||||
%define STDOUT 1
|
||||
%define STDERR 2
|
||||
|
||||
;; sched.h
|
||||
%define CLONE_VM 0x00000100
|
||||
%define CLONE_FS 0x00000200
|
||||
%define CLONE_FILES 0x00000400
|
||||
%define CLONE_SIGHAND 0x00000800
|
||||
%define CLONE_PARENT 0x00008000
|
||||
%define CLONE_THREAD 0x00010000
|
||||
%define CLONE_IO 0x80000000
|
||||
|
||||
;; sys/mman.h
|
||||
%define MAP_GROWSDOWN 0x0100
|
||||
%define MAP_ANONYMOUS 0x0020
|
||||
%define MAP_PRIVATE 0x0002
|
||||
%define PROT_READ 0x1
|
||||
%define PROT_WRITE 0x2
|
||||
%define PROT_EXEC 0x4
|
||||
|
||||
%define THREAD_FLAGS \
|
||||
CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_PARENT|CLONE_THREAD|CLONE_IO
|
||||
|
||||
%define STACK_SIZE (4096 * 1024)
|
||||
|
||||
%define MAX_LINES 1000000 ; number of output lines before exiting
|
||||
|
||||
section .data
|
||||
count: dq MAX_LINES
|
||||
|
||||
section .text
|
||||
_start:
|
||||
; Spawn a few threads
|
||||
mov rdi, threadfn
|
||||
call thread_create
|
||||
mov rdi, threadfn
|
||||
call thread_create
|
||||
|
||||
.loop: call check_count
|
||||
mov rdi, .hello
|
||||
call puts
|
||||
mov rdi, 0
|
||||
jmp .loop
|
||||
|
||||
.hello: db `Hello from \e[93;1mmain\e[0m!\n\0`
|
||||
|
||||
;; void threadfn(void)
|
||||
threadfn:
|
||||
call check_count
|
||||
mov rdi, .hello
|
||||
call puts
|
||||
jmp threadfn
|
||||
.hello: db `Hello from \e[91;1mthread\e[0m!\n\0`
|
||||
|
||||
;; void check_count(void) -- may not return
|
||||
check_count:
|
||||
mov rax, -1
|
||||
lock xadd [count], rax
|
||||
jl .exit
|
||||
ret
|
||||
.exit mov rdi, 0
|
||||
mov rax, SYS_exit
|
||||
syscall
|
||||
|
||||
;; void puts(char *)
|
||||
puts:
|
||||
mov rsi, rdi
|
||||
mov rdx, -1
|
||||
.count: inc rdx
|
||||
cmp byte [rsi + rdx], 0
|
||||
jne .count
|
||||
mov rdi, STDOUT
|
||||
mov rax, SYS_write
|
||||
syscall
|
||||
ret
|
||||
|
||||
;; long thread_create(void (*)(void))
|
||||
thread_create:
|
||||
push rdi
|
||||
call stack_create
|
||||
lea rsi, [rax + STACK_SIZE - 8]
|
||||
pop qword [rsi]
|
||||
mov rdi, THREAD_FLAGS
|
||||
mov rax, SYS_clone
|
||||
syscall
|
||||
ret
|
||||
|
||||
;; void *stack_create(void)
|
||||
stack_create:
|
||||
mov rdi, 0
|
||||
mov rsi, STACK_SIZE
|
||||
mov rdx, PROT_WRITE | PROT_READ
|
||||
mov r10, MAP_ANONYMOUS | MAP_PRIVATE | MAP_GROWSDOWN
|
||||
mov rax, SYS_mmap
|
||||
syscall
|
||||
ret
|
Loading…
Reference in New Issue