Skip to content

Instantly share code, notes, and snippets.

@bencz
Last active August 18, 2021 18:22
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bencz/7dbdf3cfe270ac2f2b8f to your computer and use it in GitHub Desktop.
Save bencz/7dbdf3cfe270ac2f2b8f to your computer and use it in GitHub Desktop.
Tipo pró!
#include <stdio.h>
#if _MSC_VER
#define ASMDEF __asm
#elif __ORANGEC__ || __DMC__
#define ASMDEF asm
#endif
int xor(int a, int b)
{
// a forma mais simples de se calcular o XOR
// a+b-2*and(a,b)
int c = 0;
for (int x = 0; x <= 31; ++x)
{
c += c;
if (a < 0)
{
if (b >= 0)
{
c += 1;
}
}
else if (b < 0)
{
c += 1;
}
a += a;
b += b;
}
return c;
}
// &
int and(int a, int b)
{
int c = 0;
for (int x = 0; x <= 31; ++x)
{
c += c;
if (a < 0)
{
if (b < 0)
{
c += 1;
}
}
a += a;
b += b;
}
return c;
}
// | ( or )
int or(int a, int b)
{
int c = 0;
for (int x = 0; x <= 31; ++x)
{
c += c;
if (a < 0)
{
c += 1;
}
else if (b < 0)
{
c += 1;
}
a += a;
b += b;
}
return c;
}
int powtab[] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, -32768 };
int shiftRight(int a, int shift)
{
if (shift >= 15)
{
if (a < 0)
{
a = -1;
}
else
{
a = 0;
}
}
else if (shift > 0)
{
if (a < 0)
{
a += -32768;
a /= powtab[shift];
a -= powtab[15 - shift];
}
else
{
a /= powtab[shift];
}
}
return a;
}
unsigned int uShiftRight(int a, int shift)
{
if (shift > 15)
{
a = 0;
}
else if (shift > 0)
{
if (a < 0)
{
a += -32768;
a /= powtab[shift];
a += powtab[15 - shift];
}
else
{
a /= powtab[shift];
}
}
return a;
}
// signed
int shiftLeft(int a, int shift)
{
if (shift > 15)
{
a = 0;
}
else
{
a *= powtab[shift];
}
return a;
}
int somar(int x, int y)
{
int carry = 0;
#if (__ORANGEC__ || __DMC__ || _MSC_VER) && __USE_ASM_FUNCTIONS__
ASMDEF
{
FazSoma:
cmp[y], 0
je Exit
mov eax, [x]
and eax, [y]
mov[carry], eax
mov ecx, [x]
xor ecx, [y]
mov[x], ecx
mov edx, [carry]
shl edx, 1
mov[y], edx
jmp FazSoma
Exit:
mov eax, [x]
mov[x], eax
}
#else
while (y != 0)
{
carry = and(x, y);
x = xor(x,y);
y = shiftLeft(carry, 1);
}
#endif
return x;
}
void incrementar(int *variable, int qnt)
{
#if (__ORANGEC__ || __DMC__ || _MSC_VER) && __USE_ASM_FUNCTIONS__
ASMDEF
{
mov eax, [qnt]
push eax
mov ecx, [variable]
mov edx, [ecx]
push edx
call somar
add esp, 8 // alinha a pilha..
mov ecx, [variable]
mov[ecx], eax
}
#else
*variable = somar(*variable, qnt);
#endif
}
int negar(int x)
{
int retVal;
#if (__ORANGEC__ || __DMC__ || _MSC_VER) && __USE_ASM_FUNCTIONS__
ASMDEF
{
push 1
mov eax, [x]
not eax
push eax
call somar
add esp, 8
mov[retVal], eax
}
#else
retVal = somar(~x, 1);
#endif
return retVal;
}
int subtrair(int x, int y)
{
int retSub = 0;
#if (__ORANGEC__ || __DMC__ || _MSC_VER) && __USE_ASM_FUNCTIONS__
ASMDEF
{
mov eax, [y]
push eax
call negar
add esp, 4
push eax
mov ecx, [x]
push ecx
call somar
add esp, 8
mov[retSub], eax
}
#else
retSub = somar(x, negar(y));
#endif
return retSub;
}
int dividir_por_dois(int numero)
{
int resultado;
#if (__ORANGEC__ || __DMC__ || _MSC_VER) && __USE_ASM_FUNCTIONS__
ASMDEF
{
mov eax, [numero]
sar eax, 1
mov[resultado], eax
}
#else
resultado = shiftRight(numero,1);
#endif
return resultado;
}
int multiplicar_por_dois(int numero)
{
int resultado;
#if (__ORANGEC__ || __DMC__ || _MSC_VER) && __USE_ASM_FUNCTIONS__
ASMDEF
{
mov eax, [numero]
shl eax, 1
mov[resultado], eax
}
#else
resultado = shiftLeft(numero, 1);
#endif
return resultado;
}
int ehPar(int x)
{
int resultado;
#if (__ORANGEC__ || __DMC__ || _MSC_VER) && __USE_ASM_FUNCTIONS__
ASMDEF
{
mov eax, [x]
not eax
and eax, 1
mov[resultado], eax
}
#else
resultado = !(x & 1);
#endif
return resultado;
}
int ehImpar(int x)
{
int resultado;
#if (__ORANGEC__ || __DMC__ || _MSC_VER) && __USE_ASM_FUNCTIONS__
ASMDEF
{
mov eax, [x]
and eax, 1
mov[resultado], eax
}
#else
resultado = !(ehPar(x));
#endif
return resultado;
}
int multiplicar(int x, int y)
{
int produto = 0;
#if (__ORANGEC__ || __DMC__ || _MSC_VER) && __USE_ASM_FUNCTIONS__
ASMDEF
{
cmp[x], 0
jge MulLoop1
cmp[y], 0
jge MulLoop1
mov eax, [y]
push eax
call negar
add esp, 4
push eax
mov ecx, [x]
push ecx
push ecx
call negar
add esp, 4
push eax
call multiplicar
add esp, 8
jmp MulLoop6
MulLoop1:
cmp[x], 0
jl MulLoop2
cmp[y], 0
jge MulLoop2
mov edx, [x]
push edx
mov eax, [y]
push eax
call multiplicar
add esp, 8
jmp MulLoop6
MulLoop2:
cmp[y], 0
jle MulLoop5
mov ecx, [y]
push ecx
call ehPar
add esp, 4
test eax, eax
je MulLoop3
mov edx, [x]
push edx
call multiplicar_por_dois
add esp, 4
mov[x], eax
mov eax, [y]
push eax
call dividir_por_dois
add esp, 4
mov[y], eax
jmp MulLoop4
MulLoop3:
mov ecx, [x]
push ecx
mov edx, [produto]
push edx
call somar
add esp, 8
mov[produto], eax
push - 1
mov eax, [y]
push eax
call somar
add esp, 8
mov[y], eax
MulLoop4:
jmp MulLoop2
MulLoop5:
mov eax, [produto]
MulLoop6:
mov[produto], eax
}
#else
if (x < 0 && y < 0)
return multiplicar(negar(x), negar(y));
if (x >= 0 && y < 0)
return multiplicar(y, x);
while (y > 0)
{
if (ehPar(y))
{
x = multiplicar_por_dois(x);
y = dividir_por_dois(y);
}
else
{
produto = somar(produto, x);
y = somar(y, -1);
}
}
#endif
return produto;
}
int dividir(int dividendo, int divisor)
{
int temp = 1;
int quociente = 0;
#if (__ORANGEC__ || __DMC__ || _MSC_VER) && __USE_ASM_FUNCTIONS__
ASMDEF
{
Dividir1:
mov eax, [divisor]
cmp eax, [dividendo]
jg Dividir2
mov ecx, [divisor]
shl ecx, 1
mov[divisor], ecx
mov edx, [temp]
shl edx, 1
mov[temp], edx
jmp Dividir1
Dividir2:
cmp[temp], 1
jle Exit
mov eax, [divisor]
sar eax, 1
mov[divisor], eax
mov ecx, [temp]
sar ecx, 1
mov[temp], ecx
mov edx, [dividendo]
cmp edx, [divisor]
jl Dividir3
mov eax, [divisor]
push eax
mov ecx, [dividendo]
push ecx
call subtrair
add esp, 8
mov[dividendo], eax
mov edx, [temp]
push edx
mov eax, [quociente]
push eax
call somar
add esp, 8
mov[quociente], eax
Dividir3:
jmp Dividir2
Exit:
}
#else
while (divisor <= dividendo)
{
divisor = shiftLeft(divisor, 1);
temp = shiftLeft(temp,1);
}
while (temp > 1)
{
divisor = shiftRight(divisor, 1);
temp = shiftRight(temp, 1);
if (dividendo >= divisor)
{
dividendo = subtrair(dividendo, divisor);
quociente = somar(quociente, temp);
}
}
#endif
return quociente;
}
int main()
{
int x = 90;
int y = 18;
printf("XOR LOGICO: %d^%d=%d\n", x, y, x^y);
printf("XOR MATEMA: %d^%d=%d\n", x, y, xor(x, y));
printf("RSHIFT LOGICO: %d\n", x >> 1);
printf("RSHIFT MATEMA: %d\n", shiftRight(x, 1));
printf("URSHIFT MATEM: %d\n", uShiftRight(x, 1));
printf("LSHIFT LOGICO: %d\n", x << 1);
printf("LSHIFT MATEMA: %d\n", shiftLeft(x, 1));
printf("OR LOGICO: %d\n", x | y);
printf("OR MATEMA: %d\n", or(x, y));
printf("AND LOGICO: %d\n", x & y);
printf("AND MATEMA: %d\n", and(x, y));
int i = 0;
int incremento = 20;
printf("Somar............: 20+20=%d\n", somar(20, 20));
printf("Subtrair.........: 30-10=%d\n", subtrair(30, 10));
printf("Negar............: ~10=%d\n", negar(10));
printf("Multiplicar......: 70*27=%d\n", multiplicar(70, 27));
printf("Dividir(inteiros): 36/06=%d\n", dividir(36, 6));
printf("Multiplicar por 2: 70*02=%d\n", multiplicar_por_dois(70));
printf("Dividir por 2....: 40/02=%d\n\n", dividir_por_dois(40));
incrementar(&incremento, 1);
printf("Incrementar: 20+01=%d\n", incremento);
printf("7 eh impar.: %s\n", ehImpar(7) ? "true" : "false");
printf("2 eh impar.: %s\n", ehImpar(2) ? "true" : "false");
printf("8 eh par...: %s\n", ehPar(8) ? "true" : "false");
printf("7 eh par...: %s\n", ehPar(7) ? "true" : "false");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment