2018-04-27 20:34:02 +00:00
|
|
|
;; Hello World Program #1
|
|
|
|
;; Compile with: nasm -f elf hello.s
|
|
|
|
;; Link with: ld -m elf_i386 -o hello hello.o
|
|
|
|
;; Run with: ./hello
|
|
|
|
|
|
|
|
;; sys/unistd_32.h
|
|
|
|
%define SYS_write 4
|
|
|
|
%define SYS_exit 1
|
|
|
|
|
|
|
|
;; unistd.h
|
|
|
|
%define STDOUT 1
|
|
|
|
|
|
|
|
section .data
|
|
|
|
msg db "Okay, so we're doing 32-bit subroutines now, huh?", 0Ah, 00h
|
|
|
|
|
|
|
|
section .text
|
|
|
|
global _start
|
|
|
|
|
|
|
|
_start:
|
2018-04-27 23:44:37 +00:00
|
|
|
mov ecx, msg ; Put the address of our message into eax.
|
2018-04-27 20:34:02 +00:00
|
|
|
call strlen ; call the function strlen. We're using EAX as our argument.
|
|
|
|
call printit
|
|
|
|
call exit
|
|
|
|
|
|
|
|
strlen:
|
|
|
|
; will probably want its state restored correctly, right?
|
2018-04-27 23:44:37 +00:00
|
|
|
mov edx, ecx
|
2018-04-27 20:34:02 +00:00
|
|
|
|
|
|
|
strlen_next:
|
2018-04-27 23:44:37 +00:00
|
|
|
cmp byte [edx], 0
|
2018-04-27 20:34:02 +00:00
|
|
|
jz strlen_done
|
2018-04-27 23:44:37 +00:00
|
|
|
inc edx
|
2018-04-27 20:34:02 +00:00
|
|
|
jmp strlen_next
|
|
|
|
|
|
|
|
strlen_done:
|
2018-04-27 23:44:37 +00:00
|
|
|
sub edx, ecx ; Straight from the counted-hello file
|
2018-04-27 20:34:02 +00:00
|
|
|
ret
|
|
|
|
|
|
|
|
;; Takes EAX as the address of the message and EDX as the
|
|
|
|
;; length, and prints them. Restores all used registers
|
2018-04-27 23:44:37 +00:00
|
|
|
;; when finished. EDX contains the count.
|
2018-04-27 20:34:02 +00:00
|
|
|
printit:
|
|
|
|
push ebx
|
2018-04-27 23:44:37 +00:00
|
|
|
push eax
|
2018-04-27 20:34:02 +00:00
|
|
|
mov ebx, STDOUT
|
|
|
|
mov eax, SYS_write
|
|
|
|
int 80h
|
|
|
|
pop eax
|
2018-04-27 23:44:37 +00:00
|
|
|
pop ebx
|
2018-04-27 20:34:02 +00:00
|
|
|
ret
|
|
|
|
|
|
|
|
;; Since this terminates the program, I'm not worried about
|
|
|
|
;; managing the stack correctly.
|
|
|
|
exit:
|
|
|
|
mov ebx, 0
|
|
|
|
mov eax, SYS_exit
|
|
|
|
int 80h
|