Last active
January 8, 2024 14:42
-
-
Save AdrianCert/d64d5852f8b7414c595bccb7d5ff9877 to your computer and use it in GitHub Desktop.
ACSO fuctions: transcript between c and asm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @brief ACSO fuctions: transcript between c and asm | |
* | |
* @copyright 2020 ACSO transcript | |
* @author Adrian Panaintescu <adrian.cert@gmail.com> | |
* | |
* @details Simple functions written in cpp and "asm" organized on namespace, being available both variants as language | |
* | |
* @file | |
* | |
* @ingroup | |
* | |
*/ | |
#include <iostream> | |
using namespace std; | |
namespace cc { | |
// Structura pentru un numar complex | |
struct complex { | |
int re, im; | |
}; | |
namespace c { | |
// Afiseaza diferenta intre doua numere | |
void dif(int a, int b) { | |
cout << a - b << endl; | |
} | |
// Afiseaza descrescator numerele in mod recusiv | |
void afis(unsigned n) { | |
if (n == 0) return; | |
cout << n << endl; | |
afis(n - 1); | |
} | |
// Calculeaza factorialul unui numar recursiv | |
unsigned factorial(unsigned n) { | |
if (n < 2) return 1; | |
return n * factorial(n - 1); | |
} | |
// Apeleaza funtia dif | |
void call_dif() { | |
dif(10, 7); | |
} | |
// Calculeaza suma numelor complexe a si b | |
// Rezultatul va ajunge in c | |
void complex_suma(complex* a, complex* b, complex* c) { | |
c->im = a->im + b->im; | |
c->re = a->re + b->re; | |
} | |
// Calculeaza suma unui vector | |
int vector_suma(int* t, int n) { | |
int s = 0,i; | |
for (i = 0; i < n; i++) { | |
s += t[i]; | |
} | |
return s; | |
} | |
// Returneaza elementul unuei matrice 3x3 | |
int matrice_element(int x[][3], int i, int j) { | |
return x[i][j]; | |
} | |
// Calculeaza suma unei matrice creata dinamic 3x3 | |
// int** x = new int* [3]; | |
// for (int i = 0; i < 3; i++) | |
// x[i] = new int[3]; | |
int matrice_suma(int** x) { | |
int s = 0; | |
for (int i = 0; i < 3; i++) { | |
for (int j = 0; j < 3; j++) { | |
s += x[i][j]; | |
} | |
} | |
return s; | |
} | |
} | |
namespace asmb { | |
// Afiseaza diferenta intre doua numere | |
void dif(int a, int b) { | |
int x; | |
_asm { | |
push eax | |
mov eax, a | |
sub eax, b | |
mov x, eax | |
pop eax | |
} | |
cout << x << endl; | |
} | |
// Afiseaza descrescator numerele pana la n | |
// in mod recusiv | |
void afis(unsigned n) { | |
_asm { | |
cmp n, 0 | |
je afara | |
} | |
cout << n << endl; | |
_asm { | |
dec n | |
push n | |
call afis | |
add esp, 4 | |
afara: | |
} | |
} | |
// Calculeaza factorialul unui numar recursiv | |
unsigned factorial(unsigned n) { | |
_asm { | |
push ebx | |
mov ebx, n | |
cmp ebx, 2 | |
jae not_conditie | |
mov eax, 1 | |
jmp out_fct | |
not_conditie : | |
dec ebx | |
push ebx | |
call factorial | |
add esp, 4 | |
mul n | |
out_fct : | |
pop ebx | |
} | |
} | |
// Apeleaza funtia dif | |
void call_dif() { | |
_asm { | |
push dword ptr 7 | |
push dword ptr 10 | |
call dif | |
add esp, 8 | |
} | |
} | |
// Calculeaza suma numelor complexe a si b | |
// Rezultatul va ajunge in c | |
void complex_suma(complex* a, complex* b, complex* c) { | |
_asm { | |
add_re: | |
mov eax, a | |
mov ebx, [eax] | |
mov eax, b | |
add ebx, [eax] | |
mov eax, c | |
mov[eax], ebx | |
add_im : | |
mov eax, a | |
mov ebx, [eax + 4] | |
mov eax, b | |
add ebx, [eax + 4] | |
mov eax, c | |
mov[eax + 4], ebx | |
} | |
} | |
// Calculeaza suma unui vector | |
// se foloseste deferentierea | |
int vector_suma(int* t, int n) { | |
_asm { | |
mov eax, 0 | |
mov ebx, 0 | |
mov ecx, t | |
bucla_fct : | |
cmp ebx, n | |
jge afara_fct | |
add eax, [ecx + ebx * 4] | |
inc ebx | |
jmp bucla_fct | |
afara_fct : | |
} | |
} | |
// Returneaza elementul unuei matrice 3x3 | |
int matrice_element(int x[][3], int i, int j) { | |
_asm { | |
push ebx | |
push ecx | |
push esi | |
mov esi, x | |
mov ebx, i | |
mov ecx, j | |
mov eax, 3 | |
imul ebx | |
add ecx, eax | |
mov eax, [esi + ecx * 4] | |
pop esi | |
pop ecx | |
pop ebx | |
} | |
} | |
// Calculeaza suma unei matrice creata dinamic | |
// int** x = new int* [3]; | |
// for (int i = 0; i < 3; i++) | |
// x[i] = new int[3]; | |
int matrice_suma(int** x) { | |
_asm { | |
push ebx | |
push ecx | |
mov eax, 0 | |
mov ebx, 0 | |
bucla_i : | |
cmp ebx, 3 | |
jge afara_i | |
mov ecx, 0 | |
bucla_j : | |
cmp ecx, 3 | |
jge afara_j | |
mov edx, x | |
mov edx, [edx + ebx * 4] | |
add eax, [edx + ebx * 4] | |
inc ecx | |
jmp bucla_j | |
afara_j : | |
inc ebx | |
jmp bucla_i | |
afara_i : | |
pop ecx | |
pop ebx | |
} | |
} | |
} | |
} | |
void exercices(){ | |
/* @Title: Exercitiu 1 | |
* | |
* @Enunt: Fie următorul program care calculează factorialul unui număr. | |
Să se înlocuiască linia de cod din interiorul buclei for (f = f * i) cu un bloc de cod asm, cu obţinerea aceluiaşi efect. | |
Pentru simplificare, vom considera că rezultatul nu depăşeşte 4 octeţi. | |
* | |
* @Category: Folosirea instructiunei mul si imul | |
* / | |
unsigned int n = 10, i, f = 1; | |
for (i = 1; i <= n; i++) { | |
// f = f * i; in asm | |
_asm { | |
mov eax, f | |
mul i | |
mov f, eax | |
} | |
} | |
printf("%u\n", f); | |
/* End Exerctiu 1 */ | |
/* @Title: Exercitiu 2 | |
* | |
* @Enunt: Fie următorul program. Să se înlocuiască liniile 4 şi 5 cu un bloc de cod asm, cu obţinerea aceluiaşi efect. | |
* | |
* @Category: Folosirea instructiunei div si idiv | |
* / | |
unsigned a = 500007, b = 10, c, d; | |
_asm { | |
mov edx, 0 | |
mov eax, a | |
mov ebx, b | |
div ebx | |
mov c, eax | |
mov d, edx | |
} | |
// c = a / b; | |
// d = a % b; | |
printf("%u %u\n", c, d); | |
/* End Exerctiu 2 */ | |
} | |
int main() { | |
exercices(); | |
/* Test: dif * / | |
cc::c::dif(5, 2); | |
cc::asmb::dif(5, 2); | |
/* End Test: dif */ | |
/* Test: afis * / | |
cc::c::afis(5); | |
cc::asmb::afis(5); | |
// call afis with asm | |
_asm { | |
push dword ptr 5 | |
call cc::asmb::afis | |
add esp, 4 | |
} | |
/* End Test: afis */ | |
/* Test: factorial * / | |
cout << cc::c::factorial(6) << " " << cc::asmb::factorial(6); | |
/* End Test: factorial */ | |
/* Test: call_dif * / | |
cc::c::call_dif(); | |
cc::asmb::call_dif(); | |
/* End Test: call_dif */ | |
/* Test: complex_suma * / | |
cc::complex a = { 2,5 }, b = { 3,11 }, c; | |
cc::c::complex_suma(&a, &b, &c); | |
cout << c.re << " + " << c.im << "i" << endl; | |
cc::asmb::complex_suma(&a, &b, &c); | |
cout << c.re << " + " << c.im << "i" << endl; | |
/* End Test: complex_suma */ | |
/* Test: vector_suma * / | |
int t[] = { 1, 9, 4, 12, 3 }; | |
int suma = 0, *p = t; | |
cout << cc::c::vector_suma(t, 5) << endl << cc::asmb::vector_suma(t, 5); | |
/* End Test: vector_suma */ | |
/* Test: matrice_element * / | |
int p[3][3] = { | |
0, 1, 5, | |
7, 9, 2, | |
14, 13, 12 | |
}; | |
cout << cc::c::matrice_element(p, 2, 2) << endl << cc::asmb::matrice_element(p, 2, 2); | |
/* End Test: matrice_element */ | |
/* Test: matrice_suma * / | |
int** v; | |
v = new int* [3]; | |
for (int i = 0; i < 3; i++) { | |
v[i] = new int[3]; | |
} | |
for (int i = 0; i < 3; i++) { | |
for (int j = 0; j < 3; j++) { | |
v[i][j] = 1; | |
} | |
} | |
cout << cc::c::matrice_suma(v) << endl << cc::asmb::matrice_suma(v); | |
/* End Test: matrice_suma */ | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment