Hello world (with proper exit), in 32 and 64 bit implementations.

This commit is contained in:
Elf M. Sternberg 2018-04-25 07:56:08 -07:00
parent b5503dad30
commit 4a7fa5a427
7 changed files with 256 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
*.o
*~
\#*
.\#*

12
Makefile Normal file
View File

@ -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

30
hello32.s Executable file
View File

@ -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

29
hello64.s Normal file
View File

@ -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

48
number.s Normal file
View File

@ -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

25
something.s Normal file
View File

@ -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

108
threads-x86_64.s Normal file
View File

@ -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