Skip to content

Instantly share code, notes, and snippets.

@zuchmanski
Created April 9, 2013 12:26
Show Gist options
  • Save zuchmanski/5345312 to your computer and use it in GitHub Desktop.
Save zuchmanski/5345312 to your computer and use it in GitHub Desktop.
zad1
; 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