logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[Rozwiązano] Asembler, zadanie, kod sprawdzający poprawność działania klawiatury

11 Lip 2019 21:21 768 9
REKLAMA
  • #1 18056327
    Konto nie istnieje
    Poziom 1  
  • REKLAMA
  • #2 18056635
    _jta_
    Specjalista elektronik
    Posty: 48927
    Pomógł: 3202
    Ocena: 4214
    To wygląda na program pod DOS-a... przypuszczam, że INT 21h (jest wykorzystywany do wywoływania funkcji DOS-u) przy AH=8 czyta znak ze standardowego wejścia (jak się nie przekieruje, to z klawiatury) do AL nie dając echa, przy AH=2 wypisuje znak z DL na standardowe wyjście, a przy AH=4Ch kończy program - dlatego w programie są sekwencje "mov ah,coś" i potem "int 21h"; "cmp al,0Dh" porównuje ostatnio przeczytany znak z 0Dh, czyli CR (kod Enter), i potem "je koniec" to skok do etykiety koniec, jeśli jest równy (je = jump equal; może też być jz).

    Ale program ma błąd: loop wykona skok zmniejszając CX o 1, a jeśli CX był równy 1, to nie wykona skoku - a w programie nie ustawia się CX, więc nie wiadomo, kiedy się skończy. Wypadałoby poprawić: albo między start: i petla: wstawić np. "mov CX,1000", albo zamiast "loop" napisać "jmp".

    Można zamiast funkcji DOS-u użyć funkcji BIOS-u do czytania i pisania znaków: AH=0 INT 16h przeczyta znak do AL, AH=0Eh BL=7 INT 10h wypisze znak z AL (BL chyba podaje kolor, ale najlepiej to sprawdzić, jest strona Ralf Brown Interrupt List, tam jest właściwie wszystko o różnych INT).

    A czy znasz w ogóle architekturę procesora 8088 (bo to na taki zostało napisane)?
  • REKLAMA
  • #3 18056881
    kinggustav
    Poziom 27  
    Posty: 797
    Pomógł: 93
    Ocena: 93
    Zachował funkcjonalność, dobre. Ten program tak naprawdę nic nie robi. Czyta i wypisuje znaki dopóki nie pojawi się Enter i wychodzi. Trudno to "nic" zrobić inaczej. Można pokombinować z innymi instrukcjami skoków, ale to trochę mało. Może dołóż w segmencie dane (taki jakiś pusty teraz, a jest) zmienną i do niej zapisz ten łańcuch? To trochę skomplikuje kod.
  • Pomocny post
    #4 18056910
    _jta_
    Specjalista elektronik
    Posty: 48927
    Pomógł: 3202
    Ocena: 4214
    Można pozmieniać nazwy segmentów i etykiet - byle konsekwentnie. Można poprawić błąd, o którym napisałem - dodanie na początku "mov CX,1000" spowoduje, że po wpisaniu 1000 znaków program się zakończy, choćby nie został wciśnięty Enter.

    Na klawiaturze oprócz znaków możliwych do wyświetlenia są np. klawisze funkcyjne, strzałki, Home, End,... nie bardzo wiem, jak zostaną przeczytane przez funkcję DOS-u 08h; BIOS czyta je tak, że w AL jest 0 (albo 0E0h dla niektórych klawiszy, których nie było w starszych klawiaturach), a w AH kod klawisza. Można by spróbować jakoś interpretować te znaki, ale to już oznacza bardziej złożony program, podobnie jak np. rozpoznawanie przycisków Shift, Ctrl, Alt (one nie są czytane przez funkcję DOS-u 08h, ani przez INT 16h z AH=0, powodują zmianę flag pod adresem 040h:017h, czyta je chyba INT16h z AH=2).
  • #5 18057847
    Konto nie istnieje
    Poziom 1  
  • REKLAMA
  • Pomocny post
    #6 18057877
    _jta_
    Specjalista elektronik
    Posty: 48927
    Pomógł: 3202
    Ocena: 4214
    Etykietami są: kod dane start petla koniec - możesz te nazwy pozmieniać, byleby nie trafić w jakąś zastrzeżoną. Dane (które są puste) można wywalić (z assume, i linie segment i ends).

    Można by (o ile assembler uznaje makra - MASM i TASM uznają, parę innych też) zdefiniować makro:
    Kod: x86 Assembly
    Zaloguj się, aby zobaczyć kod
    i wszędzie zamiast "mov ah,coś" i po nim "int 21h" napisać "dos coś" - program będzie bardziej czytelny (uwaga, tam gdzieś jest "mov ah,2", "mov dl,al" i "int 21h" - z tego trzeba zrobić "mov dl,al" i "dos 2", w tej kolejności, w odwrotnej nie zadziała).

    Przed "dos 4Ch" można dodać "mov al,0" - inaczej to się wykona z AL=0Dh, i taki kod zostanie przekazany do systemu jako numer błędu.
  • #7 18061621
    kinggustav
    Poziom 27  
    Posty: 797
    Pomógł: 93
    Ocena: 93
    Jak udziwniać to inna sztuczka: zamiast mov al,0 xor ax,ax. Szybsze podobno. :-)
  • Pomocny post
    #8 18061740
    _jta_
    Specjalista elektronik
    Posty: 48927
    Pomógł: 3202
    Ocena: 4214
    To można by sprawdzić w opisie procesora. Natomiast: kod "mov ax,0" ma 3 bajty, kod "xor ax,ax" - 2 bajty, więc jest krótszy; kod "mov al,coś", czy ""mov ah,coś" ma 2 bajty.
  • REKLAMA
  • #9 18063366
    kinggustav
    Poziom 27  
    Posty: 797
    Pomógł: 93
    Ocena: 93
    No można, ale w porównaniu z wywołaniem int 21h do wyświetlania (to mało wydajny kawałek DOSa, pierwsze co zmieniałem w wymagających programach) to będzie pikuś. Nigdy mi się nie chciało tego liczyć (chodzi o dłuższe algorytmy niż pojedynczy rozkaz) choć wiem, że niektórzy liczyli. Potem procesory przyspieszyły i ... ma to teraz jeszcze mniejszy sens. Ogólnie to w assemblerze też nie było okazji programować od wielu już lat. Tu jak sądzę również nie chodzi o oprogramowanie systemowe do zadań specjalnych, ani wyjątkowo szybki układ automatyki.
  • #10 18286158
    Konto nie istnieje
    Poziom 1  

Podsumowanie tematu

✨ Użytkownik zmaga się z programowaniem w asemblerze, szczególnie z kodem do sprawdzania poprawności działania klawiatury. W odpowiedziach omówiono funkcje DOS-u, takie jak INT 21h, oraz błędy w kodzie, w tym brak ustawienia rejestru CX, co prowadzi do nieokreślonego zakończenia pętli. Sugerowano poprawki, takie jak dodanie "mov CX,1000" oraz zmiany w segmentach i etykietach, aby poprawić czytelność kodu. Wskazano również na możliwość użycia funkcji BIOS-u do obsługi klawiszy funkcyjnych oraz na różnice w długości kodu między instrukcjami "mov" a "xor". Użytkownik otrzymał pomoc w zrozumieniu kodu oraz w jego modyfikacji, co przyczyniło się do rozwiązania problemu.
Wygenerowane przez model językowy.
REKLAMA