aboutsummaryrefslogtreecommitdiff
path: root/prog5.asm
blob: ae6b5820ca6648ec11b59efe67cf823b23906ee9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
; Gotta get these loops down... seriously.
; Let's try to write a more manual puts function

section .text
global _start

print_newline:
	push ebp		; push previous function frame pointer into stack
	mov ebp, esp	; assign new frame pointer

	pusha			; save all registers
	
	mov eax, 4		; linux write syscall
	mov ebx, 1		; stdout
	mov ecx, LF		; newline char
	mov edx, 2		; 2 bytes long
	int 80h

	popa			; restore all registers

	leave			; restore stack frame
	ret

putc:
	; purpose:
	;	print character
	; arguments:
	;	ECX - character address
	push ebp		; push previous function frame pointer into stack
	mov ebp, esp	; assign new frame pointer
	pusha			; save all registers, we're about to use them up

	mov eax, 4		; linux write syscall
	mov ebx, 1		; stdout
	mov edx, 1
	int 80h

	popa			; restore all registers
	leave			; restore stack frame
	ret

puts:
	; purpose:
	;	print a NULL terminated string followed by a new line
	;	... character-by-character
	; arguments:
	;	ECX - char. string

	push ebp
	mov ebp, esp

	.loop:
		mov al, [ecx]	; copy current char into 8-bit register
		inc ecx			; increment pointer
		mov [char], al	; copy 8-bit character into `char` variable
		
		push eax		; save eax, we're modifying EAX (via al)
		push ecx		; save ecx, to replace/send single char reference

		mov ecx, char	; putc expects ECX to have a "string" so
						; copy the character into the register

		call putc		; print character to display

						; REMEMBER THE ORDER OF PUSHES
		pop ecx			; restore registers
		pop eax			; ...

		cmp al, 0		; check for NULL terminator
		jz .break		; if al == 0: break loop
		jmp .loop		; else: repeat
	
	.break:
		call print_newline	; pretend this is C... eh?
		leave				; restore stack
		ret
	
exit:
	mov eax, 1			; linux function, terminate
	mov ebx, 0			; return value
	int 80h				; linux kernel syscall
	ret


display_copyright:
	push ebp
	mov ebp, esp
	push ecx

	mov ecx, copyright
	call puts
	
	pop ecx
	leave
	ret


display_version:
	push ebp
	mov ebp, esp
	
	mov ecx, version
	call puts

	leave
	ret


_start:
	call display_copyright
	call display_version

	call exit
	ret


section .data
copyright	db	'Joseph Hunkeler (c) 2015,', 32
				db	'All things reserved and whatever.', 0
version		db	'Version 1.0.0'
LF		db	13, 10	; ascii newline

section .bss
char	resb	1	; reserve one byte for 'puts' to use as a buffer