-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathProj5_2.asm
205 lines (171 loc) · 4.28 KB
/
Proj5_2.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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
%include "asm_io.inc"
SECTION .data
msg1: db "incorrect number of command line arguments",0
msg2: db "inccorect length of the argument",0
msg3: db "inccorect first letter of the argument (should be an upper case letter)",0
msg4: db "inccorect second letter of the argument (should be 3 o4 5 or 7 or 9)",0
msg5a: db "Displaying shape of size ",0
msg5b: db " made of letters ",0
SECTION .bss
SIZE: resd 1
LETTER: resb 1
SECTION .text
global asm_main
;;; subroutine display_line
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
display_line:
enter 0,0 ; setup routine
pusha ; save all registers
mov ebx, [ebp+8] ; bl is the letter
mov ecx, [ebp+12] ; number of blanks
mov edx, [ebp+16] ; number of letters
mov esi, 1
L1: cmp esi, ecx
ja L2
mov al,' '
call print_char
inc esi
jmp L1
L2: mov esi, 1
L3: cmp esi, edx
ja L4
mov al, bl
call print_char
mov al, ' '
call print_char
inc esi
jmp L3
L4: call print_nl
popa
leave
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; subroutine display_line ends
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; subroutine display_shape
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
display_shape:
enter 0,0 ; setup routine
pusha ; save all registers
mov ebx, [ebp+8] ;bl is the letter
mov ecx, [ebp+12] ;ecx is the size
mov esi, dword 0 ; initial number of blanks
mov edi, ecx ; initial number of letters
;; edx controls the loop
mov edx, dword 0
D5: cmp edx, ecx
jae D6
push edi
push esi
push ebx
call display_line
add esp, 12
sub edi, dword 1
add esi, dword 2
inc edx
jmp D5
D6:
mov edx, dword 1
add edi, dword 2
sub esi, dword 4
D7: cmp edx, ecx
jae display_shape_end
push edi
push esi
push ebx
call display_line
add esp, 12
inc edi
sub esi, dword 2
inc edx
jmp D7
display_shape_end:
popa
leave
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; subroutine display_shape end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; subroutine asm_main
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
asm_main:
enter 0,0 ; setup routine
;; check argc, must be 2
mov eax,[ebp+8] ;; argc
cmp eax,2
je Check_length ;; check length of argv[1]
mov eax,msg1 ;; display argc error message
call print_string
call print_nl
jmp asm_main_end
Check_length:
mov ebx,[ebp+12] ;; address of argv[]
mov ecx, [ebx+4] ;; address of argv[1]
;; first letter should not be NULL
cmp byte [ecx],byte 0
je Bad_length
;; the second letter should not be NULL
cmp byte [ecx+1], byte 0
je Bad_length
;; the third letter should be NULL
cmp byte [ecx+2], byte 0
jne Bad_length
jmp Length_ok
Bad_length:
mov eax, msg2
call print_string
call print_nl
jmp asm_main_end
Length_ok:
cmp byte[ecx],'A'
jb Bad_first_letter
cmp byte[ecx],'Z'
ja Bad_first_letter
mov al, byte [ecx]
mov [LETTER], al
jmp Second_letter
Bad_first_letter:
mov eax, msg3
call print_string
call print_nl
jmp asm_main_end
Second_letter:
inc ecx
cmp byte[ecx],'0'
jb Bad_second_letter
cmp byte[ecx],'9'
ja Bad_second_letter
;; so the second letter is a digit
cmp byte[ecx], '3'
je Set_size
cmp byte[ecx], '5'
je Set_size
cmp byte[ecx], '7'
je Set_size
cmp byte[ecx], '9'
je Set_size
Bad_second_letter:
mov eax, msg4
call print_string
call print_nl
jmp asm_main_end
Set_size:
mov al, byte [ecx]
sub eax, dword '0'
mov [SIZE], eax
Arg_ok:
mov eax, [SIZE]
push eax
mov eax, 0
mov al, [LETTER]
push eax
call display_shape
add esp, 8
asm_main_end:
leave
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; subroutine asm_main end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;