Created
April 9, 2013 12:26
-
-
Save zuchmanski/5345312 to your computer and use it in GitHub Desktop.
zad1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; pusha & popa | |
.286 | |
data segment | |
; arguments string without white spaces | |
args db 128 DUP(?), '$' | |
; length of arguments string | |
args_length db 0 | |
; index of first char of each arg | |
args_indexes db 128 DUP(?) | |
; length of each arg | |
args_lengths db 128 DUP(?) | |
; raw rsa string | |
RSA_key db 17 dup(?) | |
; 0/1 version | |
version_flag db ? | |
; chess board | |
board db 153 dup(0d) | |
; some numbers for calculation | |
four db 4d | |
sixty_four db 64d | |
divisor db 17d | |
; all symbols used to draw the chessboard | |
symbols db " .o+=*BOX@%&#/^" | |
line db "+-----------------+", 10, 13, '$' | |
; error message | |
error_wrong_number_of_args db 'Please provide exactly 2 arguments', 10, 13, '$' | |
error_wrong_version db 'Please choose correct version (0/1)', 10, 13, '$' | |
error_wrong_length_of_key db 'Wrong length of key', 10, 13, '$' | |
error_wrong_key db 'Please provide valid key', 10, 13, '$' | |
data ends | |
; init stack | |
stack segment STACK | |
dw 128 DUP(?) | |
stack_top dw ? | |
stack ends | |
code segment | |
assume ss:stack, ds:data | |
start: | |
mov ax, data | |
mov ds, ax | |
call parse_arguments | |
; call print_arguments | |
call validate_arguments | |
call extract_key | |
call follow_the_rsa_key | |
call convert_visits_to_symbols | |
call mark_start_and_end | |
call draw_the_chessboard | |
call exit | |
parse_arguments: | |
; get length of all args and store in cx | |
mov cl, es:[80h] | |
; length of args (non-white chars) | |
mov di, 0 | |
; iterator for main loop | |
mov si, 0 | |
; check length of args string | |
; if blank exit app | |
cmp cx, 0 | |
je exit | |
; loop for parsing each char | |
read_next_char: | |
; store next char in al | |
; arguments - from [ds:81h] to [ds:0FFh] | |
mov al, es:[si + 81h] | |
; cmp with space | |
cmp al, 20h | |
je white_char | |
; cmp with tab | |
cmp al, 09h | |
je white_char | |
not_white_char: | |
; append char to args array | |
; ds:bx <- al | |
mov bx, seg args | |
mov ds, bx | |
mov bx, di | |
add bx, offset args | |
mov ds:[bx], al | |
; inc total length of non white chars (args) | |
inc di | |
jmp after_char | |
white_char: | |
; ax <- current position in raw args | |
; dx <- index of last white char | |
mov ax, si | |
; calc last argument length | |
; current_position - index of last white char - 1 | |
; | |
; Two cases: | |
; I. _ala____ma_kota | |
; lc | |
; => ax = 6 - 5 - 1 = 0 | |
; | |
; II. _ala____ma_kota | |
; l c | |
; | |
; => ax = = 4 - 0 - 1 | |
sub ax, dx | |
dec ax | |
; update last char index | |
mov dx, si | |
; if ax == 0 (last argument length = 0) <=> last char was also a white space | |
; then skip the loop | |
cmp ax, 0 | |
jle after_char | |
; else store index of first char of arg | |
; bx = current_position - length | |
; _ala____ma_kota | |
; c (di) = 5 | |
; l (ax) = 2 | |
; bx = 5 - 2 = 3 | |
mov bx, di | |
sub bx, ax | |
; add new argument | |
call add_argument | |
after_char: | |
; inc current positin | |
inc si | |
; dec length of args | |
dec cx | |
; unless last char go to next step | |
; IMPORTANT after parsing all string we need to parse | |
; white char one more time to save last arg! | |
cmp cx, 0 | |
je white_char | |
jg read_next_char | |
ret | |
add_argument: | |
pusha | |
call inc_args_length | |
call append_args_length | |
call append_args_indexes | |
popa | |
ret | |
; increment args_length by one | |
inc_args_length: | |
; ds:si - args_length | |
mov cx, seg args_length | |
mov ds, cx | |
mov si, offset args_length | |
; inc and store back | |
; es:di | |
mov cx, 0 | |
mov cl, ds:[si] | |
mov di, cx | |
inc cl | |
mov ds:[si], cl | |
ret | |
append_args_length: | |
; store current arg length (ax) in args_lengths | |
mov cx, seg args_lengths | |
mov ds, cx | |
mov si, offset args_lengths | |
; store ax | |
add si, di | |
mov ds:[si], al | |
ret | |
append_args_indexes: | |
; store current arg index (bx) in args_indexes | |
mov cx, seg args_indexes | |
mov ds, cx | |
mov si, offset args_indexes | |
; store bx | |
add si, di | |
mov ds:[si], bl | |
ret | |
; finnaly we can print arguments | |
print_arguments: | |
pusha | |
; get and save arg count | |
mov cx, seg args_length | |
mov ds, cx | |
mov si, offset args_length | |
; clear cx, store args_length for loop | |
mov cx, 0 | |
mov cl, ds:[si] | |
; print total number of arguments | |
mov ax, cx | |
call print_number | |
; iterator for loop | |
mov di, 0 | |
print_argument_loop: | |
; | |
; get argument length | |
mov ax, seg args_lengths | |
mov ds, ax | |
mov si, offset args_lengths | |
; offset + current_index | |
add si, di | |
; and store in bx | |
mov bx, 0 | |
mov bl, ds:[si] | |
; | |
; get argument index | |
mov ax, seg args_indexes | |
mov ds, ax | |
mov si, offset args_indexes | |
; offset + current_index | |
add si, di | |
; and store in ax | |
mov ax, 0 | |
mov al, ds:[si] | |
; finnaly print each arg | |
call print_argument | |
; next iteration | |
inc di | |
cmp di, cx | |
jl print_argument_loop | |
popa | |
ret | |
print_argument: | |
pusha | |
; each arg in new line | |
call print_new_line | |
; store arg length as iterator | |
mov cx, bx | |
mov di, 0 | |
; calculate new offset (with index of arg) | |
mov si, ax | |
add si, offset args | |
; and segment | |
mov ax, seg args | |
mov ds, ax | |
; print char from ds:si | |
print_char_loop: | |
mov dl, ds:[si] | |
call print_char | |
; next char | |
inc si | |
inc di | |
cmp di, cx | |
jl print_char_loop | |
popa | |
ret | |
validate_arguments: | |
pusha | |
mov cx, seg args_length | |
mov ds, cx | |
mov si, offset args_length | |
mov cx, 0 | |
mov cl, ds:[si] | |
mov ax, cx | |
cmp ax, 2d | |
je validate_arguments_cont | |
mov al, 0h | |
call raise_error | |
validate_arguments_cont: | |
popa | |
ret | |
extract_key: | |
mov di, offset RSA_key | |
push di | |
; first arg - version number | |
mov cx, seg args_length | |
mov ds, cx | |
mov si, offset args_length | |
; clear cx, store args_length for loop | |
mov cx, 0 | |
mov cl, ds:[si] | |
mov di, 0 | |
mov ax, seg args_lengths | |
mov ds, ax | |
mov si, offset args_lengths | |
; offset + current_index | |
add si, di | |
; and store in bx | |
mov bx, 0 | |
mov bl, ds:[si] | |
; | |
; get argument index | |
mov ax, seg args_indexes | |
mov ds, ax | |
mov si, offset args_indexes | |
; offset + current_index | |
add si, di | |
; and store in ax | |
mov ax, 0 | |
mov al, ds:[si] | |
mov cx, bx | |
mov di, 0 | |
; calculate new offset (with index of arg) | |
mov si, ax | |
add si, offset args | |
; and segment | |
mov ax, seg args | |
mov ds, ax | |
mov dl, ds:[si] | |
call save_version_number | |
inc di | |
; parse hex pairs | |
; | |
; get argument length | |
mov ax, seg args_lengths | |
mov ds, ax | |
mov si, offset args_lengths | |
; offset + current_index | |
add si, di | |
; and store in bx | |
mov bx, 0 | |
mov bl, ds:[si] | |
; | |
; get argument index | |
mov ax, seg args_indexes | |
mov ds, ax | |
mov si, offset args_indexes | |
; offset + current_index | |
add si, di | |
; and store in ax | |
mov ax, 0 | |
mov al, ds:[si] | |
; print first char | |
; each arg in new line | |
call print_new_line | |
; store arg length as iterator | |
mov cx, bx | |
call validate_key_length | |
; calculate new offset (with index of arg) | |
mov si, ax | |
add si, offset args | |
; and segment | |
mov ax, seg args | |
mov ds, ax | |
mov di, offset RSA_key | |
valid_pair_iterate: | |
call parse_valid_pair | |
mov dl, ds:[si] | |
inc si | |
cmp dl, ':' | |
je valid_pair_iterate | |
mov byte ptr [di], '$' | |
pop di | |
ret | |
parse_valid_pair: | |
mov dl, ds:[si] | |
mov ah, dl | |
call print_char | |
inc si | |
mov dl, ds:[si] | |
mov al, dl | |
call print_char | |
inc si | |
call two_bytes_ascii_hex_to_bin | |
mov byte ptr [di], al | |
inc di | |
call print_new_line | |
ret | |
;; SAVE VERSION NUMBER | |
save_version_number: | |
sub dl, 48d | |
cmp dl, 0d | |
je save_version_number_cont | |
cmp dl, 1d | |
je save_version_number_cont | |
mov al, 1h | |
call raise_error | |
save_version_number_cont: | |
mov byte ptr version_flag, dl | |
ret | |
validate_key_length: | |
pusha | |
cmp cx, 47d | |
je validate_key_length_cont | |
mov al, 2h | |
call raise_error | |
validate_key_length_cont: | |
popa | |
ret | |
; | |
; converts 2 bytes HEX to BIN | |
; in: | |
; ax = ah + al - ASCII HEX | |
; WYJŒCIE: | |
; al - BIN | |
; ah - error code | |
; | |
two_bytes_ascii_hex_to_bin: | |
push cx | |
push bx | |
mov bx, ax | |
mov al, bh | |
; convert 4 first bytes | |
call ascii_hex_to_bin | |
cmp ah, 1d | |
je not_hex_error | |
; move 4 bytes to the left | |
shl al, 4d | |
mov bh, al | |
; convert 4 next bytes | |
mov al, bl | |
call ascii_hex_to_bin | |
cmp ah, 1d | |
je not_hex_error | |
add al, bh | |
mov ah, 0d | |
not_hex_error: | |
pop bx | |
pop cx | |
ret | |
; | |
; convert ASCII to BIN | |
; in: | |
; al - ASCII HEX | |
; out: | |
; al - BIN | |
; | |
ascii_hex_to_bin: | |
mov ah, 0d ; domyslnie przyjmujemy ze dane sa dobre | |
; if al < '0' | |
cmp al, '0' | |
jb input_error | |
cmp al, '9' | |
ja not_digit | |
; (0..9) | |
; -48 | |
sub al, 48d | |
ret | |
not_digit: | |
; (..'A') | |
cmp al, 'A' | |
jb input_error | |
; ('F'..) | |
cmp al, 'F' | |
ja not_big_letter | |
; ('A'..'Z') | |
; -55 | |
sub al, 55d | |
ret | |
not_big_letter: | |
; (..'a') | |
cmp al, 'a' | |
jb input_error; | |
; ('f'..) | |
cmp al, 'f' | |
ja input_error; | |
; -87 | |
; ('a'..'z') | |
sub al, 87d | |
ret | |
input_error: | |
mov al, 3h | |
call raise_error | |
; | |
; follow the chessboard in order to calculate visits with laufer | |
; in: | |
; ds:RSA_key - key | |
; ds:board - chessboard | |
; | |
;---------------------------------------------------------------------------------------------- | |
follow_the_rsa_key: | |
push cx | |
push si | |
mov si, offset RSA_key | |
; move laufer in the center | |
mov di, 76d | |
; save his visit in there | |
inc byte ptr [di+board] ; zaznaczanie wizyty w tablicy | |
; iterate through RSA key | |
next_byte: | |
mov al, [si] ; pobieram do al analizowany bajt z wejscia | |
; check if end of string | |
cmp al, '$' | |
je end_of_input | |
mov cx, 4d | |
analyse_bits: | |
mov ah, 0 | |
; ah + al | |
call extract_new_pair | |
cmp ah, 00b | |
jne step1 | |
call up_left | |
jmp last | |
step1: | |
cmp ah, 01b | |
jne step2 | |
call up_right | |
jmp last | |
step2: | |
cmp ah, 10b | |
jne step3 | |
call down_left | |
jmp last | |
step3: | |
call down_right | |
last: | |
; save position of laufer | |
inc byte ptr [di+board] | |
; analyse last two bits | |
loop analyse_bits | |
; bext byte | |
inc si | |
jmp next_byte | |
end_of_input: | |
pop si | |
pop cx | |
ret | |
; | |
; extract next pair | |
; in: | |
; ds:version_flag | |
; al - number | |
; out: | |
; ah - direction | |
; al - rest | |
; | |
; | |
; 0 CASE (moves last number to ah by shifting <dividing>) | |
; 43 | |
; ah ; al | |
; 00 00 00 00 ; 00 10 10 11 | |
; 00 00 00 11 ; 00 00 10 10 | |
; 00 00 00 10 ; 00 00 00 10 | |
; 00 00 00 10 ; 00 00 00 00 | |
; 00 00 00 00 ; 00 00 00 00 | |
; | |
; 1 CASE (moves first number to ah by shifting <dividing>, rotating) | |
; 43 | |
; ah ; al | |
; 00 00 00 00 ; 00 10 10 11 | |
; 00 00 00 00 ; 10 10 11 00 | |
; 00 00 00 10 ; 10 11 00 00 | |
; 00 00 00 10 ; 11 00 00 00 | |
; 00 00 00 10 ; 00 00 00 00 | |
extract_new_pair: | |
push cx | |
cmp byte ptr [version_flag], 1d | |
je modification | |
div four | |
pop cx | |
ret | |
modification: | |
; divide by 64 | |
div sixty_four | |
; swap al with ah | |
xchg al, ah | |
; fill two bits with zeros | |
mov cl, 2d | |
shl al, cl | |
pop cx | |
ret | |
; move laufer | |
; in: | |
; di - coords of laufer before action | |
; out: | |
; di - coords of laufer after action | |
up_right: | |
push ax | |
; corner | |
cmp di,16d | |
je end_ur | |
mov ax, di | |
div divisor | |
; wall | |
cmp ah, 16d | |
jne wall_ur | |
; go top | |
sub di, 17d | |
jmp end_ur | |
wall_ur: | |
; top | |
cmp al, 0d | |
jne ceiling_ur | |
; go right | |
inc di | |
jmp end_ur | |
; go up right | |
ceiling_ur: | |
sub di, 16d | |
end_ur: | |
pop ax | |
ret | |
up_left: | |
push ax | |
; corner | |
cmp di, 0d | |
je end_ul | |
mov ax, di | |
div divisor | |
; wall | |
cmp ah, 0d | |
jne wall_ul | |
; to top | |
sub di,17d | |
jmp end_ul | |
; top | |
wall_ul: | |
cmp al, 0d | |
jne ceiling_ul | |
; go left | |
dec di | |
jmp end_ul | |
; go up left | |
ceiling_ul: | |
sub di,18d | |
end_ul: | |
pop ax | |
ret | |
down_right: | |
push ax | |
; corner | |
cmp di, 152d | |
je end_dr | |
mov ax, di | |
div divisor | |
; wall | |
cmp ah, 16d | |
jne wall_dr | |
; bottom | |
add di,17d | |
jmp end_dr | |
; bottom | |
wall_dr: | |
cmp al, 8d | |
jne floor_dr | |
; right | |
inc di | |
jmp end_dr | |
; go down right | |
floor_dr: | |
add di, 18d | |
end_dr: | |
pop ax | |
ret | |
down_left: | |
push ax | |
; corner | |
cmp di, 136d | |
je end_dl | |
mov ax, di | |
div divisor | |
; wall | |
cmp ah,0d | |
jne wall_dl | |
; go bottom | |
add di, 17d | |
jmp end_dl | |
wall_dl: | |
; bottom | |
cmp al,8d | |
jne floor_dl | |
; go left | |
dec di | |
jmp end_dl | |
; go down loeft | |
floor_dl: | |
add di, 16d | |
end_dl: | |
pop ax | |
ret | |
; | |
; convert chess board with number of vistits with ascii symbols | |
; in | |
; ds:board - chess borad with visits | |
; ds:symbols - array of symbols | |
; out: | |
; ds:board - chess board filled with symbols | |
; | |
convert_visits_to_symbols: | |
push di | |
mov di, offset board | |
mov cx, 153d | |
convert: | |
mov ax, 0 | |
mov al, [di] | |
mov si, ax | |
cmp si, 14d | |
jbe under14 | |
; if greater than 14 leave 14 | |
mov ax, 14d | |
mov si, ax | |
under14: | |
; chose char from array and replace it | |
mov al, [si+symbols] | |
mov byte ptr [di], al | |
inc di | |
loop convert | |
mov byte ptr [di], '$' | |
pop di | |
ret | |
; | |
; replace first symbol with S and the last one with E | |
; | |
mark_start_and_end: | |
mov byte ptr [76d+board], 'S' | |
mov byte ptr [di+board], 'E' | |
ret | |
; | |
; draws the chessboard | |
; in: | |
; ds:board - chessboard | |
; | |
draw_the_chessboard: | |
push cx | |
push dx | |
mov si, offset board | |
call print_new_line | |
call print_line | |
; iterate thrugh each row | |
next_row: | |
cmp byte ptr [si], '$' | |
je finish | |
call print_wall | |
; 17 chars in one line | |
mov cx, 17d | |
row: | |
mov dl, [si] | |
inc si | |
call print_char | |
loop row | |
call print_wall | |
call print_new_line | |
jmp next_row | |
finish: | |
call print_line | |
pop dx | |
pop cx | |
ret | |
;; OUT HELPER METHODS | |
print_char: | |
pusha | |
mov ah, 02h | |
int 21h | |
popa | |
ret | |
print_new_line: | |
pusha | |
mov dl, 10 | |
call print_char | |
popa | |
ret | |
print_number: | |
pusha | |
; convert number to ASCII number | |
add ax, "0" | |
mov dl, al | |
call print_char | |
popa | |
ret | |
print_line: | |
mov ah, 9h | |
mov dx, offset line | |
int 21h | |
ret | |
print_wall: | |
mov dl, '|' | |
call print_char | |
ret | |
exit: | |
mov ah, 4ch | |
int 21h | |
raise_error: | |
cmp al, 0h | |
jne next_error | |
mov dx, offset error_wrong_number_of_args | |
next_error: | |
cmp al, 1h | |
jne next_error2 | |
mov dx, offset error_wrong_version | |
next_error2: | |
cmp al, 2h | |
jne next_error3 | |
mov dx, offset error_wrong_length_of_key | |
next_error3: | |
cmp al, 3h | |
jne next_error4 | |
mov dx, offset error_wrong_key | |
next_error4: | |
mov ah, 9h | |
int 21h | |
call exit | |
code ends | |
end start |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment