Created
May 17, 2019 21:06
-
-
Save zxmarcos/fd5880fe2fa00173ee6512f690bc974a to your computer and use it in GitHub Desktop.
Write in C
This file contains hidden or 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
/* "Write in C" | |
* Marcos Medeiros | |
*/ | |
#include <stdio.h> | |
#include <string.h> | |
#include <stdlib.h> | |
unsigned char *__xbufbase = NULL; | |
unsigned int __xbufsize = 0; | |
unsigned int __xbufpos = 0; | |
static const char *__partes[6] = { | |
"When I find my code in tons of trouble,\n" | |
"Friends and colleagues come to me,\n" | |
"Speaking words of wisdom:\n", | |
"As the deadline fast approaches,\n" | |
"And bugs are all that I can see,\n" | |
"Somewhere, someone whispers\n", | |
"I used to write a lot of FORTRAN,\n" | |
"for science it worked flawlessly.\n" | |
"Try using it for graphics!\n", | |
"If you've just spent nearly 30 hours\n" | |
"Debugging some assembly,\n" | |
"Soon you will be glad to\n", | |
"And when the screen is fuzzy,\n" | |
"And the edior is bugging me.\n" | |
"I'm sick of ones and zeroes.\n", | |
"A thousand people people swear that T.P.\n" | |
"Seven is the one for me.\n" | |
"I hate the word PROCEDURE,\n", | |
}; | |
static const char *__comun = "\"Write in C\"\n\n"; | |
static const char *__refrao = { | |
"Write in C, write in C,\n" | |
"Write in C, %s write in C.\n" | |
"%s\n" | |
"Write in C.\n\n", | |
}; | |
static const char *__refrao_muda[6] = { | |
"LISP is dead and buried,", | |
"Only wimps use BASIC.", | |
"Pascal won't quite cut it.", | |
"Don't even mention COBOL.", | |
"PL1 is 80's,", | |
"The government loves ADA," | |
}; | |
void w8(unsigned char v) | |
{ | |
if (__xbufpos < __xbufsize) { | |
__xbufbase[__xbufpos] = v; | |
__xbufpos++; | |
} else { | |
printf("w8 overflow!\n"); | |
} | |
} | |
void w16(unsigned short v) | |
{ | |
if ((__xbufpos + 2) < __xbufsize) { | |
unsigned char *ptr = &__xbufbase[__xbufpos]; | |
*((unsigned short *) ptr) = v; | |
__xbufpos += 2; | |
} else { | |
printf("w16 overflow!\n"); | |
} | |
} | |
void w32(unsigned int v) | |
{ | |
if ((__xbufpos + 4) < __xbufsize) { | |
unsigned char *ptr = &__xbufbase[__xbufpos]; | |
*((unsigned int *) ptr) = v; | |
__xbufpos += 4; | |
} else { | |
printf("w32 overflow!\n"); | |
} | |
} | |
#define PUSH_N(v) w8(0x68); w32((unsigned)(v)) | |
#define ADD_ESP_N(v) w16(0xc481); w32((unsigned)(v)) | |
#define RET() w8(0xc3) | |
void call_f(void *f) { | |
int displace = (unsigned) f; | |
w8(0xe8); | |
displace -= (int)(&__xbufbase[__xbufpos + 4]); | |
w32(displace); | |
} | |
void executar() | |
{ | |
typedef void (*vfunc)(); | |
vfunc f; | |
f = (vfunc) __xbufbase; | |
f(); | |
} | |
void emitir_refrao(int n, int t) | |
{ | |
static const char *__v[3] = { | |
"", "yeah,", "oh," | |
}; | |
PUSH_N((unsigned int)__refrao_muda[n]); | |
PUSH_N((unsigned int) __v[t]); | |
PUSH_N((unsigned int)__refrao); | |
call_f((void *)&printf); | |
ADD_ESP_N(12); | |
} | |
void emitir_parte(int n) | |
{ | |
PUSH_N((unsigned int)__partes[n]); | |
call_f((void *)&printf); | |
ADD_ESP_N(4); | |
PUSH_N((unsigned int)__comun); | |
call_f((void *)&printf); | |
ADD_ESP_N(4); | |
} | |
/* | |
* Aqui a música é definida como uma simples máquina de estados | |
*/ | |
void emitir_musica() | |
{ | |
int estrofe = 0; | |
int parte = 0; | |
int refrao = 0; | |
int t_refrao = 0; | |
do { | |
switch (estrofe) { | |
case 0: | |
case 1: | |
case 3: | |
case 4: | |
case 8: | |
case 9: | |
emitir_parte(parte); | |
parte++; | |
break; | |
case 2: | |
t_refrao = 0; | |
goto __ref; | |
case 6: | |
t_refrao = 2; | |
goto __ref; | |
case 5: | |
case 7: | |
case 10: | |
case 11: | |
t_refrao = 1; | |
__ref: | |
emitir_refrao(refrao, t_refrao); | |
refrao++; | |
break; | |
} | |
estrofe++; | |
} while (estrofe < 12); | |
RET(); | |
} | |
int main() | |
{ | |
/* Aloca nosso buffer de emissão de código */ | |
__xbufsize = 4096; | |
__xbufbase = (unsigned char *) malloc(__xbufsize); | |
if (!__xbufbase) { | |
printf("Não foi possível alocar memória!\n"); | |
return 1; | |
} | |
__xbufpos = 0; | |
/* gera o código da nossa música */ | |
emitir_musica(); | |
executar(); | |
free(__xbufbase); | |
__xbufbase = NULL; | |
__xbufpos = 0; | |
__xbufsize = 0; | |
system("pause"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment