Drobna pomoc z programem w asemblerze.

0

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


0

To się nie wykona nigdy:

@readi:
  mov byte [bx], al
  inc bx

Co zaś do wyboru,to najprościej Ci będzie konsolą-wyświetlasz coś w rodzaju "Wybierz operacje do przeprowadzenia przed podanie kodu operacji:\n1.Dodawanie\n2.Odejmowanie\n" itd
Się uprzesz to możesz rysować guziki menu korzystając z kodów ascii od ramek,do myszy też się odwołasz-tutaj wskazówka,jeśli zrobisz w ten sposób to badaj zdarzenie zwolnienia lewego przycisku myszy l)

1 użytkowników online, w tym zalogowanych: 0, gości: 1