RazzorFlame Temat założony przez niniejszego użytkownika |
Assembler [NASM] - 1 lekcja z kursu Bogdro » 2013-01-25 21:36:13 Jako że troche już umiem asma (chodzi że troche załapałem o co biega w tych rejestrach) to próbowałem zakodzić sobie coś co pobiera klawisz i wypisuje go na ekran. Może mam złe przyzwyczajenia z C++ ale czytając: INT 16 - KEYBOARD - GET KEYSTROKE AH = 00h Return: AH = BIOS scan code AL = ASCII character
Mam wrażenie że został w rejestrze AL zapisany numer klawisza lub jego odpowiednik w ASCII. Tak więc mam kod: org 100h
start: mov ah, 9 mov dx, info int 21h
xor ah, ah ;xorujemy rejestr (8bitowy) ah (akumulator) int 16h ;przerwanie - Get KeyStroke mov ah, 9 ;po wcisnieciu klawisza znowu chce uzyc funkcji do wypisywania na ekran mov dl, al ;przypisuje do rejestru dl - 8 bitowy rejestr danych int 21h ;standardowe przerwanie ;wzorowalem sie na wyswietlenie zmiennej 'info' zawierającą ciąg znaków "Czesc" xor ah, ah ;znowu xoruje i czekam az wcisniemy klawisz int 16h
mov ax, 4Ch int 21h
info db "Czesc!$"
Jednak trochu się przeliczyłem bo wyświetlają się śmieci (skąd ja to wiedziałem x]). Możecie wskazać co jest nie tak? Chciałem se troche pomużdzyć i mieć satysfakcje z 1 napisanego dobrze programu w asmie. |
|
m4tx |
» 2013-01-25 21:52:29 xor ah, ah
Wut? Średnio znam asma, ale liczba xor liczba to przecież 0... :P |
|
pekfos |
» 2013-01-25 21:56:14 Jest to jedna z metod zerowania rejestru ;) |
|
RazzorFlame Temat założony przez niniejszego użytkownika |
» 2013-01-25 21:57:36 No tak, właśnie. Ale przecież musze przypisać wartość 0 (np przexorować co jak pisze bogdro jest szybsze) bo inaczej funkcja się nie wykona. Oto cytat z jego kursu: nie jest najlepszym sposobem na wyzerowanie danego rejestru. Szybsze lub krótsze są dwa inne:
xor rej1, rej1 ; 1 xor 1 = 0 oraz 0 xor 0 = 0. ; Stąd "coś XOR to_samo_coś" ; zawsze daje 0. |
EDIT: To jednak nie rozwiązuje mojego problemu. |
|
pekfos |
» 2013-01-25 22:00:22 Przerwanie 21h przy ah równym 9, wypisuje string spod adresu dx zakończony znakiem dolara, tak? Więc w chwili wywołania w dh masz śmieci, a w dl wczytany kod. Otrzymany adres wskazuje na jakieś śmieci.
//Edit: czy przypadkiem kod zakańczania (4ch) nie powinien być w ah, a nie al? |
|
RazzorFlame Temat założony przez niniejszego użytkownika |
» 2013-01-25 22:09:45 Więc w chwili wywołania w dh masz śmieci, a w dl wczytany kod |
No racja, ale czy ja chcę wypisać cokolwiek z rejestru dh? Do rejestru dl przecież wpisuje wartość z rejestru al więc powinno wyświetlić to co jest w dh czyli w tym przypadku wartość z rejestru al. Tak to wygląda bynajmniej według mnie? Może są jakieś operacje o których nie wiem... Kto wie :) EDIT: czeaj czeaj coś kapuje. Bogdro pisał że EDX (32 bitowy) dzieli się na 2x16bitów (DX, i starsze bity), zaś DX dzieli się na DH, i DL (każde po 8 bitów). Chyba że chodzi że te starsze bity z EDX to te DH i DL ( sumie 16 bitów ). EDIT x2: RAX (64 bity) | EAX (32b) 00000000000000000000000000000000 | 0000000000000000 | 00000000 | 00000000 32b | 16b | AX(16b) | | AH(8b) | AL(8b) |
Jest tu pokazne odnośnie RAX jednak dzieli się on tak samo jak RDX... Tak więc jednak się nie pomyliłem i chyba te "starsze bity" poprostu są nie używane. |
|
pekfos |
» 2013-01-25 22:14:38 const char * str =( char * ) 'a'; cout << str; To robisz, rozumiesz? Przerwanie 21h z ah = 9 wyświetla string spod adresu dx. Do dl przypisujesz kod, w dh masz śmieci. Ten adres nie może być poprawny. Zamiast tego użyj przerwania 21h z ah = 2 i dl = znak. |
|
RazzorFlame Temat założony przez niniejszego użytkownika |
» 2013-01-25 22:21:21 Heh już lepiej, jednak zawsze mi wyświetla taki znaczek choby ->
Edit: Nie czytajcie tego UP. Podczas rozmowy podmieniłem dl na dh i coś sie "pokićkało" i jest dobrze. Dziękuje pekfos. Teraz musze se tylko obczaić co znacza te przerwanie przy ah = 2 i int 21h (jeśliby ci się chciało możesz napisać :D) |
|
« 1 » 2 |