Zaznaczę na początku że jestem w miarę nowy w temacie asemblera. No więc mam tu taki programik, dodający 2 liczby. Wiem jak zrobić żeby wykonywał wszystkie działania, tyle że pojedynczo, moje pytanie to jak zrobić coś w rodzaju menu na starcie programu, żeby wybrać czy program ma dodawać/odejmować/dzielić/mnożyć. Dodam jeszcze że pracuję z kompilatorem NASM.
org 100h
jmp main_code
; wczytujemy z klawiatury
; BX - adres do zmiennej, w ktorej zostanie zapisana liczba
read_input:
jmp @next
@readi:
mov byte [bx], al
inc bx
@next:
mov ah, 1
int 21h
cmp al, 0Dh
jne @readi
ret
;------------------------
; robimy konwersje string to int (a wlasciwie to dword)
; BX - adres do tekstu
; AX - rezultat
str_to_int:
push si
xor dx, dx
xor ax, ax
mov si, bx
jmp @spr
@conv:
sub dl, '0'
mov cx, ax
add ax, ax
shl cx, 3
inc si
add ax, cx
add ax, dx
@spr:
mov dl, [si]
test dl, dl
jnz @conv
pop si
ret
;-------------------------------
; zamieniamy dworda na string
; ax - dword
;
dw_to_string:
mov bx, 10
xor cx, cx
divLoop:
xor dx, dx
div bx
push dx
inc cx
or ax, ax
jnz divLoop
storeLoop:
pop ax
add al, '0'
mov [di], al
inc di
loop storeLoop
mov byte [di], 0
ret
;-----------
; si - bufor wejsciowy
; ax - rezultat w hex (dword)
; zamieniamy stringa w postaci np. '1234' na hex, ktory zmiesci sie w 16 bitach
decStr_to_hex:
xor cx, cx
xor dx, dx
mov bx, 0Ah
push si
jmp @dd
@strlen:
inc cx
@dd:
lodsb
cmp al, 0
jne @strlen
pop si
mov di, cx
jmp @bb
@power:
push dx
@aa:
cmp cx, 1
jne @ee
pop dx
clc ; czyscimy flage carry
add dx, ax
jc invalid_number ; b. wazne sprawdzenie! jc - jump if carry (skacz jezeli flaga carry ustawiona)
; flaga jest ustawiana gdy rejestr sie przepelni i nie pomiesci danych, wiec np.
; gdy podamy wartosc wieksza niz 65 535
dec di
mov cx, di
jmp @bb
@ee:
mul bx
cmp cx, 0
loopne @aa ; cx = cx - 1
pop dx
add dx, ax
dec di
mov cx, di
@bb:
xor ax, ax
lodsb
cmp al, 0
je @cc
and al, 0Fh
jmp @power
@cc:
ret
;-------------
invalid_number:
mov ah, 9h
mov dx, invalid_num
int 21h
jmp @end
;-----------------------
invalid_result:
mov ah, 9h
mov dx, invalid_res
int 21h
jmp @end
;-----------------------
; main code
main_code:
; liczba 1
mov bx, number_a_str
call read_input
mov si, number_a_str
call decStr_to_hex ; dx - calc_result str_to_int
mov [number_a_dw], dx
;----------------
; liczba 2
mov bx, number_b_str
call read_input
mov si, number_b_str
call decStr_to_hex ; dx - calc_result str_to_int
mov [number_b_dw], dx
;-----------------
mov ax, [number_a_dw]
mov dx, [number_b_dw]
clc
add ax, dx ; dodawanie
jc invalid_result
; zamieniamy to co jest w DX (suma) na string
mov di, calc_result
call dw_to_string ; ax - calc_result dw_to_string, di - bufor
mov ah, 9h
mov dx, calc_result
int 21h
jmp @end
@end:
; koniec
mov ax, 4C00h
int 21h
; ---- zmienne
number_a_str times 16 db 0
number_b_str times 16 db 0
calc_result times 16 db "", "$"
number_a_dw dd 0
number_b_dw dd 0
invalid_num db "Invalid number, max allowed value should be less or equal 65 535 (0xFFFF)$"
invalid_res db "Result is too big and exceeds max allowed value of 65 535 (0xFFFF) which single 16-bit register can accomodate$"
; EOF