Завдання 1: Проробити тестові приклади та варіанти індивідуальних завдань. Скласти звіт. Завдання 2: Проробити тестові приклади та варіанти індивідуальних завдань. Скласти звіт. № Регістри для пересилки 8/16/32 розрядних даних Дані 8/16/32 Знакові (-) Беззнакові (+)
4 DL/DX/AX 14h /8888h /33338888h +/-/-
Код програми: Випадок А: #include "stdafx.h" #include "iostream.h" int main(int argc, char* argv[]) { unsigned char b=0x14; unsigned char a=0; cout << "Before MOVE Assembler: a= "<< a <<" b= "<< b <<endl << endl; _asm { mov dL,b mov a,dL } cout << "After MOVE Assembler:a= "<< a <<" b= "<< b <<endl << endl; printf(" AFTER MOVE a=%i b=%i \n",a,b); return 0; } Результат програми: Before MOVE Assembler: a= b= ¶ After MOVE Assembler:a= ¶ b= ¶ AFTER MOVE a=20 b=20 Press any key to continue Випадок В: #include "stdafx.h" #include "iostream.h" int main(int argc, char* argv[]) { short int b=0x8888; short int a=0; cout << "Before MOVE Assembler: a= "<< a <<" b= "<< b <<endl << endl; _asm { mov ax,b mov a,ax } cout << "After MOVE Assembler:a= "<< a <<" b= "<< b <<endl << endl; printf(" AFTER MOVE a=%i b=%i \n",a,b); return } Результат програми: Before MOVE Assembler: a=0 b= -30584 After MOVE Assembler:a= -30584 b= -30584 After MOVE a= -30584 b= -30584 Press any key to continue Випадок С: #include "stdafx.h" #include "iostream.h" int main(int argc, char* argv[]) { int b=0x33338888; int a=0; cout << " Before MOVE Assembler: a= " << a <<" b= "<< b<< endl << endl; _asm { mov ax, WORD PTR b ; ax<=== молодша частина a mov bx, WORD PTR b+2 ; bx<=== старша частина a mov WORD PTR a, ax ; молодша частина x<=== <ax> mov WORD PTR a+2, bx ; старша частина x<=== <bx> } cout << " After MOVE Assembler: a= " << a <<" b= "<< b<< endl << endl; //printf(" AFTER MOVE a= %i b=%i \n",a,b); return 0; } Результат програми: Before MOVE Assembler: a=0 b= 859015304 After MOVE Assembler:a= 859015304 b= 859015304 Press any key to continue Завдання 3: Використовуючи асемблерні інструкції додавання та інкременту, обчислити значення виразу. Порівняти отримані дані із даними отриманими в С++. № Вираз для обчислення Значення a/b/c Знакові (-) Беззнакові (+)
4 a+(8b)+c+12 14h/0888h /03338888h +/-/-
Код програми: #include "stdafx.h" #include "iostream.h" int main(int argc, char* argv[]) { char a=0x14; short int b=0x0888; int c=0x03338888; int d=0; printf("a= %i, b= %i, c= %i \n",a,b,c); __asm { mov EAX,0 mov EBX,0 mov ECX,0 mov EDX,0 mov AL, a mov BX,b mov ECX,c adc BX,BX adc BX, b adc BX, b adc BX, b adc BX, b adc BX, b adc BX, b adc EBX, ECX; adc EBX,12 adc EBX,EAX mov d,EBX } printf("Assembler: d=a+(8b)+c+12= %i \n",d); d=a+8*b+c+12; printf(" C++ : d=a+(8b)+c+12= %i \n",d); return 0; } Результат програми: a=20, b=2184, c=53708936 Assembler: d=a+(8b)+c+12= 53726440 C++ : d=a+(8b)+c+12= 53726440 Press any key to continue Завдання 4: Використовуючи асемблерні інструкції додавання/віднімання та інкременту/декременту, обчислити значення виразу. Порівняти отримані дані із даними отриманими в С++. № Вираз для обчислення Значення a/b/c Знакові (-) Беззнакові (+)
4 a-(8b-1)+c+12 03338888h /0888h /14h +/-/-
Код програми: #include "stdafx.h" #include "iostream.h" int main(int argc, char* argv[]) { unsigned long int a=0x03338888; short int b=0x0222; char c=0x13; int d=0; printf("a= %i, b= %i, c= %i \n",a,b,c); __asm { mov EAX,0 ; mov EBX,0 ; mov ECX,0 ; mov EDX,0 ; mov ax,b adc eax,eax adc eax,eax adc eax,eax dec eax mov EBX,a sbb EBX,EAX mov cl,c adc EBX,ECX inc EBX inc EBX inc EBX inc EBX inc EBX inc EBX inc EBX inc EBX inc EBX inc EBX inc EBX inc EBX mov d,EBX } printf("Assembler: d=a-(8*b-1)+c+12= %i \n",d); d=a-(8*b-1)+c+12; printf(" C++ : d=a-(8*b-1)+c+12= %i \n",d); return 0; } Результат програми: a= 53708936, b= 546, c= 19 Assembler: d=a-(8*b-1)+c+12= 53704600 C++ : d=a-(8*b-1)+c+12= 53704600 Press any key to continue Завдання 5: Не використовуючи асемблерні інструкції віднімання, обчислити значення виразу. Використати 32 розрядні регістри та команди розширення, або зміни знаку. Множення замінити додаванням. Усі дані вважати знаковими. Скомпілювати приклад. Запустити програму у відладчику. Порівняти отримані результати обчислень із аналогічними в С++. № Вираз для обчислення Значення a/b/c
4 3(a+b-1)-8c+1 0x30 /0x0826 /0x0404826
Код програми: #include "stdafx.h" #include "iostream.h" int main(int argc, char* argv[]) { int a=0x30; int b=0x10826; int c=0x0404826; int d=0; printf("a= %i, b= %i, c= %i \n",a,b,c); __asm { //***** a+b-1 **** mov Al,0x30; a mov EBX,0x10826; b CBW CWDE add EAX,EBX; dec EAX; //*****3(a+b-1)**** mov ecx,eax add eax,eax add eax,ecx //***** -8c+1 ***** mov EDX,c; add EDX,EDX; add EDX,EDX; add EDX,EDX; neg EDX add eax,edx inc EAX mov d,EAX } printf("Assembler: d=3(a+b-1)-8c+1= %i \n",d); d=3*(a+b-1)-8*c+1; printf(" C++ : d=3(a+b-1)-8c+1= %i \n",d); return 0; } Результат програми: a= 48, b= 67622, c= 4212774 Assembler: d=3(a+b-1)-8c+1= -33499184 C++ : d=3(a+b-1)-8c+1= -33499184 Press any key to continue Завдання 6: Використовуючи асемблерні інструкції MOV, ADD, ADC, INC, SUB, SBB, DEC, NEG,MUL, IMUL обчислити значення виразу (операцію множення додаванням не замінювати). Виконати завдання спочатку для випадку беззнакового (MUL), а потім для знакового (IMUL) множення. При виконанні завдання, максимально оптимізувати асемблерний код (зробити мінімальну кількість інструкцій). Пояснити розбіжності рахунків Асемблера та С++, якщо такі були отримані. Порівняти отримані дані із даними отриманими в С++. № Вираз для обчислення Значення a/b/c