-
Notifications
You must be signed in to change notification settings - Fork 2
/
toupper.asm
176 lines (146 loc) · 3.97 KB
/
toupper.asm
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
; PURPOSE: This program converts an input file to an output file
; with all letters converted to uppercase.
; PROCESSING: 1) Open the input file
; 2) Open the output file
; 3) While we're not at the end of the input file
; a) read part of file into our memory buffer
; b) go through each byte of memory
; if the byte is a lower case letter
; convert it to uppercase
; c) write the memory buffer to output file
; CONSTANTS
section .data
; System call numbers
SYS_OPEN equ 0x2000005
SYS_WRITE equ 0x2000004
SYS_READ equ 0x2000003
SYS_CLOSE equ 0x2000006
SYS_EXIT equ 0x2000001
; Options for open
O_RDONLY equ 0
O_CREAT_WRONLY_TRUNC equ 03101
; Standard file descriptors
STDIN equ 0
STDOUT equ 1
STDERR equ 2
EOF equ 0
NUMBER_ARGUMENTS equ 2
section .bss
; Buffer - this is where the data is loaded into
; from the data file and written from into
; the output file. This should never exceed 16,000
; for various reasons
BUFFER_SIZE equ 500
buffer:
resb BUFFER_SIZE
; Stack positions
ST_SIZE_RESERVE equ 16 ; Stack size to reserve for file descriptors
ST_FD_IN equ -8
ST_FD_OUT equ -16
ST_ARGC equ 0 ; Number of arguments
ST_ARGV_0 equ 8 ; Name of program
ST_ARGV_1 equ 16 ; Input file name
ST_ARGV_2 equ 24 ; Output file name
section .text
global start
start:
mov rbp, rsp
; Allocate space for our file descriptions
; on the stack
sub rsp, ST_SIZE_RESERVE
open_files:
open_fd_in:
; open syscall
mov rax, SYS_OPEN
mov rdi, [rbp + ST_ARGV_1] ; user_addr_t path
mov rsi, O_RDONLY ; int flags
mov rdx, 0666 ; int mode
syscall
store_fd_in:
mov [rbp + ST_FD_IN], rax
open_fd_out:
; open syscall
mov rax, SYS_OPEN
mov rdi, [rbp + ST_ARGV_2] ; path
mov rsi, O_CREAT_WRONLY_TRUNC ; flags
mov rdx, 0666 ; mode
syscall
store_fd_out:
mov [rbp + ST_FD_OUT], rax
; Begin main loop
read_loop_begin:
mov rax, SYS_READ
mov rdi, [rbp + ST_FD_IN]
mov rsi, buffer
mov rdx, BUFFER_SIZE
syscall
; Exit if we reached the end
cmp rax, EOF
jle end_loop
continue_read_loop:
lea rsi, [rel buffer]
push rsi
push rax
call convert_to_upper
pop rax
add rsp, 8
; Write the block out to the output file
mov rdx, rax ; buffer size (from read return), last arg to write
mov rax, SYS_WRITE
mov rdi, [rbp + ST_FD_OUT]
mov rsi, buffer
syscall
; Continue the loop
jmp read_loop_begin
end_loop:
; Close the files
mov rax, SYS_CLOSE
mov rdi, [rbp + ST_FD_IN]
syscall
mov rax, SYS_CLOSE
mov rdi, [rbp + ST_FD_OUT]
syscall
mov rax, SYS_EXIT
mov rdi, 0
syscall
; PURPOSE: This function actually does the conversion to upper case for a block
; conversion to upper case for a block
; INPUT: The first parameter is the location
; of the block of memory to convert
; The second parameter is the length of that buffer
; OUTPUT: This function overwrites the current buffer with the uppercase version.
;
; VARIABLES
; rax - Beginning of buffer
; rbx - Length of buffer
; rdi - Current buffer offset
; cl - Current byte being examined (first part of ecx)
LOWERCASE_A equ 'a'
LOWERCASE_Z equ 'z'
UPPER_CONVERSION equ 'A' - 'a'
ST_BUFFER_LEN equ 16
ST_BUFFER equ 24
convert_to_upper:
push rbp
mov rbp, rsp
mov rax, [rbp + ST_BUFFER]
mov rbx, [rbp + ST_BUFFER_LEN]
mov rdi, 0
cmp rbx, 0
je end_convert_loop
convert_loop:
mov cl, [rax + rdi]
cmp cl, LOWERCASE_A
jl next_byte
cmp cl, LOWERCASE_Z
jg next_byte
add cl, UPPER_CONVERSION
mov [rax + rdi], cl
next_byte:
inc rdi
cmp rbx, rdi
jne convert_loop
end_convert_loop:
mov rsp, rbp
pop rbp
ret