Simples JIT (just in time) em C
Publicado por ??? (última atualização em 08/07/2013)
[ Hits: 3.623 ]
Este é um simples exemplo de um JIT (just in time) escrito em puro C para Windows e GNU/Linux em 32 bits.
Este exemplo gera uma simples função que chama outra função (hello)...
Espero que seja útil para alguém.
//------------------------------------------------------------------- // // THANKS TO: // The only GOD, creator of heaven and earth, in the name of JESUS CHRIST. // // DESCRIPTION: // A simples JIT (32 bits) x86. // // FILE: // asm.c // // COMPILE: // gcc asm.c -o asm -m32 -O2 -Wall // // BY: gokernel - gokernel@hotmail.com // //------------------------------------------------------------------- #include <stdio.h> #include <stdlib.h> #ifdef __linux__ #include <unistd.h> #include <sys/mman.h> // for: mprotect #endif typedef struct ASM { unsigned char *code; int len; }ASM; ASM *asm_new (int size) { ASM *a = (ASM*) malloc (sizeof(ASM)); a->code = (unsigned char*) malloc (size); a->len = 0; return a; } //------------------------------------------------------------------- // This function use the code of Fabrice Bellard: // // LIB: tcc-0.9.25 // FILE: libtcc.c // FUNC: void set_pages_executable (void *ptr, unsigned long length); // LINE: 400 // // Set executable: a->code // //------------------------------------------------------------------- void asm_set_executable (ASM *a) { #ifdef __linux__ unsigned long start, end, PageSize; PageSize = sysconf (_SC_PAGESIZE); start = (unsigned long)a->code & ~(PageSize - 1); end = (unsigned long)a->code + a->len; end = (end + PageSize - 1) & ~(PageSize - 1); mprotect ((void *)start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC); #endif } // 1 byte void asm_gen (ASM *a, unsigned char c) { *(unsigned char*)(a->code + a->len) = c; a->len++; } // 4 bytes void asm_get_addr (ASM *a, void *ptr) { *(void**)(a->code + a->len) = ptr; a->len += sizeof (void*); } // 7 bytes void asm_op_call (ASM *a, void *func) { // b8 7a 13 40 00 mov $0x40137a,%eax // ff d0 call *%eax // asm_gen (a, 0xb8); asm_get_addr (a, func); asm_gen (a, 0xff); asm_gen(a, 0xd0); } void hello (void) { printf ("\ncall function: Hello World\n\n"); } void execute (void) { ASM *a = asm_new (1000); if (a && a->code) { //----------------------------------------------------------- asm_gen(a, 0x55); // push %ebp asm_gen(a, 0x89); asm_gen(a, 0xe5); // mov %esp,%ebp asm_op_call (a, hello); asm_gen(a, 0xc9); // leave asm_gen(a, 0xc3); // ret //----------------------------------------------------------- asm_set_executable (a); // execute here // ( (void(*)())a->code ) (); free (a->code); free (a); } } int main (void) { execute (); printf ("Exiting with sucess !!!\n"); return 0; }
Relógio em assembly NES 8 bits (variante do 6502)
Escrita de número em octal em Assembly puro para Linux 64 bits (NASM - Netwide Assembler)
Assembler 8086 - Simples código que mostra horas e minutos em pontos
Intercessão entre dois vetores em Assembly
"Clear Screen" para Linux x86 com Inline Assembly (embutido no código) em C
Como gerar qualquer emoji ou símbolo unicode a partir do seu teclado
Instalar e Configurar o Slackware Linux em 2025
Como configurar os repositórios do apt no Debian 12 em 2025
Passkeys: A Evolução da Autenticação Digital
Instalação de distro Linux em computadores, netbooks, etc, em rede com o Clonezilla
Configurando o Conky para iniciar corretamente no sistema
3 configurações básicas que podem melhorar muito a sua edição pelo editor nano
Como colorir os logs do terminal com ccze
Instalação Microsoft Edge no Linux Mint 22
Como configurar posicionamento e movimento de janelas no Lubuntu (Openbox) com atalhos de teclado
Linux Mint não conecta Wi-Fi sem fio (21)
Criar perfil temporário no Active Directory samba4-21 (2)
Meu Kubuntu não inicia, além do modo de recuperação (no meu dualboot (1)