Zadania z terminu zerowego
1. Napisać funkcję asemblerową:
int asm_main(int pierwszy, int drugi)
która sprawdzi, czy oba parametry funkcji są tego samego znaku. Jeżeli pierwszy i drugi są jednocześnie dodatnie lub jednocześnie ujemne funkcja powinna zwrócić wartość 1. Jeżeli pierwszy i drugi mają przeciwne znaki (na przykład pierwszy jest dodatni a drugi ujemny) to funkcja powinna zwrócić 0. Dla ułatwienia zakładamy, że pierwszy i drugi nie będą przyjmowały wartości 0.
2. Napisać funkcję asemblerową:
unsigned int asm_main()
która zwróci liczbę, odpowiadającą tablicy znaków cyfry. Zakładamy – do wyboru – że w tablicy tej znajduje się ile znaków, lub że ciąg cyfr kończy się bajtem o wartości 0. Jeżeli przykładowo cyfry[] = „901” to tablica ta zawiera w praktyce bajty o wartościach 57, 48, 49, 0. Tym samym aby obliczyć liczbę odpowiadającą tej tablicy należy systematycznie pobierać bajty z tablicy, odejmować od nich 48 i tę różnicę dodawać do uprzedniego pośredniego wyniku pomnożonego przez 10, tak aby ostatecznie otrzymać wynik o wartości 901.
(rozwiązanie by R.Radzisz)
3. Napisać funkcję asemblerową:
int asm_main()
która sprawdzi, ile zer kończy binarną reprezentację zmiennej liczba. Jeżeli przykładowo liczba = 96 to jej binarna reprezentacja ma postać:
0000000001100000
Ponieważ liczba ta ma na końcu 5 zer, funkcja powinna zwrócić wartość 5.
1.
C++
1 2 3 4 5 6 7 8 9 10 11 | #include using namespace std; extern "C" { int asm_main(int a, int b); } int main() { int wynik = asm_main(-1,2); return 0; } |
ASM
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | .386 ;Instrukcje procesora 80386 .MODEL FLAT, C ;Model rozmieszczenia programu w pamieci (FLAT) i wywolywania funkcji (C) .CODE ;Poczatek segmentu przeznaczonego na instrukcje asm_main PROC push ebp ; pobieranie parametrów ze stosu mov ebp, esp mov eax, [ebp+8] ; pierwszy param mov ebx, [ebp+12] ; drugi param cmp eax, -1 jg pierwsza_dodatnia pierwsza_ujemna: ; pierwsza ujemna cmp ebx, -1 jg druga_dodatnia mov eax,1 ; jeżeli obie ujemne wynik 1 jmp koniec druga_dodatnia: mov eax,0 ; pierwsza ujemna druga dodatnia wynik 0 jmp koniec pierwsza_dodatnia: ; pierwsza dodatnia cmp ebx, -1 jg druga_dodatnia2 mov eax,0 jmp koniec ; pierwsza dodatnia druga ujemna wynik 0 druga_dodatnia2: mov eax,1 ; obie dodatnie wynik 1 jmp koniec koniec: pop ebp ;!! wazne ret ;Powrot z funkcji asm_main ENDP END |
2.
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 | #include using namespace std; extern "C" { char cyfry[] = "902"; unsigned int ile = 3; unsigned int asm_main(void); } int main() { unsigned int wynik = asm_main(); return 0; } |
ASM
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | .386 ;Instrukcje procesora 80386 .MODEL FLAT, C ;Model rozmieszczenia programu w pamieci (FLAT) i wywolywania funkcji (C) EXTERN cyfry:BYTE ;Zmienna zadeklarowana w innym module EXTERN ile:DWORD .CODE ;Poczatek segmentu przeznaczonego na instrukcje asm_main PROC ;Definicja procedury (funkcji) "asm_main" mov ebx,0 ;licznik mov edx,0 mov ecx, ile ; licznik do petli petla: mov al, cyfry[ebx*1] ; pobieranie bajtów po kolei sub al, 48 ;wynika z treści zadania imul edx,10 ; jw. movsx eax, al ; przeniesienie bajtu do eax add edx, eax ; dodanie wyniku pośredniego do wyniku całkowitego add ebx, 1 loop petla mov eax, edx ret ;Powrot z funkcji; funkcja zwraca eax asm_main ENDP END |
3.
C++
1 2 3 4 5 6 7 8 9 10 11 12 | #include using namespace std; extern "C" { int liczba = 192; int asm_main(); } int main() { int wynik = asm_main(); return 0; } |
ASM
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | .386 ;Instrukcje procesora 80386 .MODEL FLAT, C ;Model rozmieszczenia programu w pamieci (FLAT) i wywolywania funkcji (C) EXTERN liczba:DWORD ;Zmienna zadeklarowana w innym module .CODE ;Poczatek segmentu przeznaczonego na instrukcje asm_main PROC ;Definicja procedury (funkcji) "asm_main" mov ebx, liczba mov eax, 0 ; licznik petla: ror ebx, 1 ; funkcja rotate right zapisuje najmłodszy bit w carry flag więc jeżeli jest 1 w cf przestajemy odliczać jc koniec ; jump if carry flag add eax, 1 ; eax pełni tutaj funkcje licznika jmp petla koniec: ret ;Powrot z funkcji; funkcja zwraca eax asm_main ENDP END |
bonus1.
asm
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | .386 ;Instrukcje procesora 80386 .MODEL FLAT, C ;Model rozmieszczenia programu w pamieci (FLAT) i wywolywania funkcji (C) .CODE ;Poczatek segmentu przeznaczonego na instrukcje asm_main PROC push ebp ; pobieranie parametrów ze stosu mov ebp, esp mov eax, [ebp+8] ; pierwsza liczba mov ebx, [ebp+12] ; druga liczba mov edx, eax imul eax, edx imul eax, edx cmp eax, ebx jne rozne mov eax, 1 ; wynik 1 jmp koniec rozne: mov eax, 0 ; wynik 0 koniec: pop ebp ; ret asm_main ENDP END |
bonus3.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | .386 ;Instrukcje procesora 80386 .MODEL FLAT, C ;Model rozmieszczenia programu w pamieci (FLAT) i wywolywania funkcji (C) EXTERN liczba:DWORD ;Zmienna zadeklarowana w innym module .CODE ;Poczatek segmentu przeznaczonego na instrukcje asm_main PROC ;Definicja procedury (funkcji) "asm_main" mov ebx, liczba mov eax, 0 ; licznik mov cx, 32 petla: shl ebx, 1 jnc brak add eax, 1 ;eax pełni tutaj funkcje licznika brak: loop petla cmp eax ,1 je rowne mov eax, 0 jmp koniec rowne: mov eax, 1 koniec: ret ;Powrot z funkcji; funkcja zwraca eax asm_main ENDP END |
x3:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | .386 .MODEL FLAT, C EXTERN liczba:DWORD .CODE asm_main PROC mov ebx, liczba mov eax, 0 etykieta: ror ebx, 1 jnc koniec add eax, 1 jmp etykieta koniec: ret asm_main ENDP END |
Comments