elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Recopilación Tutoriales y Manuales Hacking, Seguridad, Privacidad, Hardware, etc


  Mostrar Temas
Páginas: 1 2 [3]
21  Programación / Programación General / Robusteciendo las Prácticas de Programación con Estándares de Lenguajes y C en: 4 Julio 2012, 14:48 pm
El kernel que he escrito y al que me refiero es el del Nivel 1 en este repositorio:

>> Lista de Núcleos de Entrenamiento (solamente Nivel 1 por ahora) <<


El kernel al que me refiero ha llegado a lo que yo llamo el Nivel 1 de desarrollo.

Eso significa que es el nivel mínimo de usabilidad de un núcleo, que pueda serle útil a un usuario.

El nivel mínimo funcionalmente utilizable (Nivel 1) es poder leer programas del directorio raíz de un floppy mediante sus nombres cortos de archivo, enlazado dinámico básico, funciones de sistema exportadas para los programas, entrada de usuario con un teclado PS/2 y una consola de comandos muy básica.

-------------------------

En lo personal, escribir en ensamblador me es bastante fácil, y sería perfecto si el ensamblador x86 se usara por el resto de plataformas.

Pero ya que ese no es el caso, existen lenguajes como C, que tienen convenciones definidas para codificar sus tipos de datos, y llamadas a rutinas, pasado de parámetros, etc.

Este es una pequeña coyuntura clave: Escribí un programa en C que usa las funciones exportardas del kernel. Al comparar la forma en que se escribe un programa en C, su código generado y la falta de convenciones que usan las funciones de mi kernel actual, me llego a dar cuenta que puedo terminar de robustecer mi kernel si insisto en escribir programas en C y en ensamblador, e incluso reescribir el kernel en C y en ensamblador para comparar el código generado, y empezar a adoptar las convenciones, para obtener una portabilidad e interoperabilidad máximas.

Ya que los estándares de C y las convenciones necesarias son muy voluminosas y técnicas, esto no puede tomarse como una adivinanza, así que voy a tener que reunir esos documentos de especificaciones y traducirlos para estudiarlos a profundidad.

También voy a necesitar aprender a programar en C y en ensamblador para más de una plataforma, para poder ser capaz de crear código portable en todos los niveles. Debería por ejemplo aprender una plataforma ARM además de x86-16, x86-32 y x86-64.

-------------------------

Al usar las funciones del kernel como las tengo actualmente, me doy cuenta de que necesito especificar registros del CPU en el código de C a compilarse por GCC. Esto puede hacerse portable si uso mi lenguaje y compilador Real C, pero en GCC eso es un problema de portabilidad de plataformas enorme.

Este es el primer punto en el que voy a robustecer el kernel: Voy a aprender cómo codificar cualquier tipo de parámetros de funciones y variables de todo tipo.

El código de un programa escrito en C requiere más trabajo y más archivos, algo como esto:


"include/external_exported_functions.inc"
Código:
;Nota: Este archivo es para ser usado por programas externos,
;      para que sepan dónde encontrar las funciones que desean
;      usar, desde la tabla de funciones exportadas del kernel.

;Estos son los ÍNDICES de cada puntero en la tabla de exportes.
;Las convertimos a posiciones de 4 bytes para programas de 32 bits,
;y a posiciones de 8 bytes para programas de 64 bits.
;;

                           clrscr@KernelCore equ 0
           console_kprint_visible@KernelCore equ 1
           console_doCRLFeffect@KernelCore   equ 2
cmdLine__findFirstBlankSpace@KernelCore      equ 3
cmdLine__findFirstNonBlankSpace@KernelCore   equ 4
adjustCommandLineFATname@KernelCore          equ 5
getCommandLineArgsCount@KernelCore           equ 6
copyCommandLineArg@KernelCore                equ 7
cmdLine__charTypeAt@KernelCore               equ 8
cmdLine__skipNonBlankSpaces@KernelCore       equ 9
cmdLine__skipBlankSpaces@KernelCore          equ 10






"exports.asm"
Código:

;Aquí anteponemos un guión bajo a todas las
;funciones de ensamblador a ser llamadas desde C;
;esto es llamado "mangling" o decoración, y es
;una convención de C/el enlazador, para enlazar
;funciones externas al código de C, o entre módulos,
;especialmente entre lenguajes que no comparten las
;convenciones de C, como el caso del ensamblador.
;;

%include "include/external_exported_functions.inc"


global myImportsFunctionsTable
       global _clrscr
       global _console_kprint_visible
       global _console_doCRLFeffect
       global _adjustCommmandLineFATname
       global _getCommandLineArgsCount
       global _copyCommandLineArg
       global _cmdstrbuff


myImportsFunctionsTable:
                   ImportsCount dd 6
                           _clrscr dd clrscr@KernelCore
           _console_kprint_visible dd console_kprint_visible@KernelCore
           _console_doCRLFeffect   dd console_doCRLFeffect@KernelCore
_adjustCommandLineFATname          dd adjustCommandLineFATname@KernelCore
_getCommandLineArgsCount           dd getCommandLineArgsCount@KernelCore
_copyCommandLineArg                dd copyCommandLineArg@KernelCore






_cmdstrbuff times 1024 db 0



"header.asm"
Código:

;Aquí hemos optado por establecer a APPBASE
;simplemente a la ubicación actual en el código,
;representada por el signo de dólar, $.
;
;Ahora no es nuestro código en ensamblador el que
;debe encargarse de establecer la dirección base
;del ejecutable, sino que el enlazador LD, por el
;hecho de que estamos usando varios módulos por
;separado, y en esta complejidad solamente el enlazador
;puede llevar a cabo esto eficientemente.
;;
 ;APPBASE equ 1048576*2
 APPBASE equ $

extern myImportsFunctionsTable

;Nuestro kernel debe leer esta dirección, saltar
;a esta y luego saltarse la cabecera del ejecutable:
;;
 IntendedBaseAddress  dq APPBASE
 NumberOfFieldsBelow  dq 7
 CommandLinePtr       dq 0
 CommandLineLength    dq 0
 CommandLineParamsPtr dq 0
 KernelFnExportsTable dq 0
 KernelVrExportsTable dq 0
 AppFnImportsTable    dq myImportsFunctionsTable
 AppVrImportsTable    dq 0


"start.asm"
Código:
;Si hay código presente, debemos usar
;BITS 32:
;;
 bits 32


;La etiqueta llamada "start"
;debe ser globalmente conocida, para que
;LD o más bien otros módulos de este
;programa pueda encontrarla adecuadamente.
;
;Este es el punto de entrada de nuestra
;aplicación.
;
;"start" es el símbolo que el script LD
;para esta aplicación busca para establecer
;el punto de entrada de la misma, y debe
;declararse como global.
;;
 global start



;Estas son las funciones del kernel, con
;un guión bajo al inicio ("mangled") para
;que C pueda encontrarlas.
;
;Indicamos que son externas porque estos símbolos
;están definidos en "exports.asm":
;;
 extern _clrscr
 extern _console_kprint_visible
 extern _console_doCRLFeffect
 extern _adjustCommmandLineFATname
 extern _getCommandLineArgsCount
 extern _copyCommandLineArg






start:

;Limpiamos la pantalla como siempre:
;;
 call dword[_clrscr]

;Declaramos el símbolo "_main" como
;externo, ya que se encuentra en "main.c",
;y llamamos a main, que está declarado como
;int main(void), al menos de acuerdo a nuestro
;kernel actual y también para esta aplicación
;específica.
;
;Debemos aprender a implementar
;int main(int argc, char **argv)
;por nosotros mismos:
;;
 extern _main
 call _main


;Aquí le devolvemos el control
;al kernel:
;;
 ret



"main.c"
Código:
//Ya que nuestras funciones importadas
//están en una tabla de punteros de funciones,
//debemos declarar la función como un puntero
//a una función, para generar el código adecuado:
///
 extern void (*console_doCRLFeffect)(void);


int main(void)
{
 //Aquí colocaremos una lista de instrucciones
 //para demostrar la sintaxis de AT&T de GAS
 //para ensamblador inline, de todas las
 //combinaciones de opcodes y expresiones que
 //sea útil recordar:
 ///
  __asm__ __volatile__ ("pushl %eax");
  __asm__ __volatile__ ("popl %eax");


 //Llamamos nuestra función proveniente
 //del kernel. Ya que esta no toma parámetros,
 //podemos usarla libremente sin temor a
 //un mal manejo de los parámetros y la pila.
 //Pero esto será un problema para funciones de
 //la librería del kernel que usen parámetros, a
 //menos que estén totalmente de conformidad a
 //las convenciones de C (cdecl):
 ///
  console_doCRLFeffect();

 //Devolvemos 0 desde main, que en las x86
 //lo coloca en AX/EAX/RAX:
 ///
  return 0;
}


"link.ld"
Código:
OUTPUT_FORMAT("binary")
ENTRY(start)
phys = 0x0000000000200000;
SECTIONS
{
  .text phys : AT(phys) {
    code = .;
    *(.text)
    *(.rodata)
    . = ALIGN(0);
  }
  .data : AT(phys + (data - code))
  {
    data = .;
    *(.data)
    . = ALIGN(0);
  }
  .bss : AT(phys + (bss - code))
  {
    bss = .;
    *(.bss)
    . = ALIGN(0);
  }
  end = .;
}


"build.bat"
Código:
nasm -f aout -o header.o header.asm
nasm -f aout -o start.o start.asm
gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -c -o main.o main.c
nasm -f aout -o exports.o exports.asm

ld -T link.ld -o kern0 header.o start.o main.o exports.o


En "build.bat" (o un script Bash de Linux), el orden en el que se compilan los diferentes componentes es arbitrario; pero el orden en que se enlazan con LD es físicamente el mismo que el especificado en la línea de comandos, y debe estar en el orden mostrado aquí (cabecera del programa, inicializador en ensamblador, programa principal, otros archivos de código opcionales, y la tabla de exportes).

link.ld está configurado para generar un archivo binario crudo, y usar una alineación de 0 entre secciones.

Con un script más personalizado, podríamos indicar un ejecutable crudo pero encargarnos nosotros mismos de generar a mano el formato del ejecutable (PE, ELF, AOUT, MZ-EXE, etc.).

Ya que estamos usando el formato AOUT para crear el código objeto de cada pieza del programa mostrado aquí, también deberíamos aprender a manejar dicho formato a bajo nivel, para eventualmente crear herramientas propias y llevar a cabo tareas de depuración y desarrollo más potentes.
22  Programación / Programación General / Programación en Ensamblador (de Java): Hola Mundo en: 3 Julio 2012, 00:37 am
Como nota inicial, si alguien no tiene una mejor idea de cuál sería la mejor forma de que escriba varios posts como respuestas seguidas, incluso quizás después de varias semanas, pido disculpas si envío respuestas a este tema o abro otros nuevos, porque seguramente va a ser mucha la complejidad a manejar, y repartir las diferentes etapas de descubrimientos es mucho más fácil repartiéndolas en diferentes posts, temas y/o respuestas (que serían continuas a menos que alguien responda o consulte algo, o tenga una idea de qué más averiguar o hacer algo interesante y útil con todo esto desde ya, aparte obviamente de realmente aprender Java).

Me tomo la libertad de escribir sobre la programación en ensamblador, pero en el lenguaje dictado por el bytecode de Java.

Las razones más importantes de esto son:

- Para personas demasiado acostumbradas a trabajar con lenguajes al nivel de C o más bajos, trabajar con un ensamblador en un entorno nativo a la orientación a objetos hace mucho más fácil entender a cabalidad cómo funciona realmente la orientación a objetos, en este caso, de Java.

- Dado que Java es una plataforma unificada sin importar el hardware sobre el que corra, estudiarlo a nivel de ensamblador es una oportunidad excepcionalmente buena para practicar la ingeniería inversa y obtener un nivel de experticia por lo menos intermedio.

- Siendo expertos en el ensamblador de Java y en el formato de archivos de bytecode (.class), así como en el uso de las diferentes APIs y teniendo experticia suficiente para escribir un compilador no optimizador como mínimo, se puede dejar de usar el lenguaje Java para producir programas de Java, y eventualmente es posible usar virtualmente cualquier otro lenguaje de programación (incluso ensamblador de Intel x86, e incluso enmascarando las APIs de Java para usarlas como "alias" de otras plataformas como WinAPI o javascript, y así "recortar" un poco lo que se necesita aprender, y unificar un mismo conocimiento en diferentes ambientes de desarrollo). Esto puede llegar a ser especialmente útil, porque significaría que muchos programas escritos lenguajes que tradicinalmente tienen poca o ninguna portabilidad entre plataformas de hardware pueden reutilizarse, convirtiéndolos en instrucciones de bytecode de Java.

- El ensamblador de Java es extremadamente valioso. Los lenguajes de ensamblador "normales" son evitados por la mayoría de programadores no solo por su complejidad, sino que por el hecho de que no están pensados para ser portables. Con Java, los programas generados son más simples que los ejecutables ELF de Linux, y el ensamblador que se escriba en una plataforma, puede correr en cualquier otra en la que haya una JVM. Eso significa que se pueden hacer tareas interesantes de muy bajo nivel, que al mismo tiempo incluyan programación "moderna" orientada a objetos, con la posibilidad de poder seguir corriendo el mismo código en otras plataformas.


Todo esto suena muy interesante, pero para lograrlo, siendo indistintamente buenos programadores de C/ensamblador por ejemplo, o buenos programadores de Java (aunque a un nivel común y corriente, no a nivel de ensamblador y de la arquitectura central), este proceso puede llevar no menos de un año, durante el que hay que releer cosas como el Tutorial de Java, compilar los programas de ejemplo, hacer ingeniería inversa intensa y desensamblarlos (NO decompilarlos, sino que inspeccionar los archivos binarios a mano si es posible y/o hacer un parser), y leer una y otra vez las partes de las especificaciones que se están aplicando en cada ejemplo compilado.

------------------------------------------------------
------------------------------------------------------
------------------------------------------------------
------------------------------------------------------

Pongo un ejemplo simple de un Hola Mundo, como el del Tutorial de Java, pero en Ensamblador de Java.

No he usado un ensamblador nativo de Java "apropiado" sino que NASM, que entre otras cosas no permite usar Big Endian (Java) sino solo Little Endian (x86), así que se ve rápidamente la necesidad de usar un programa ensamblador ya sea de ARM que use Big Endian por defecto, crear un ensamblador propio para Java (en javascript por ejemplo), o buscar un ensamblador "apropiado" nativo a Java.

Esto debe compilarse con lo siguiente, ya sea en Windows, Linux, etc.:

nasm EHLOWorldApp.asm -o EHLOWorldApp.class


Código:
;/*****************************************************************************
;EHLOWorldApp.java
;
; 2012-07-02
;
;
;Demostración inicial de un programa de Java escrito totalmente en ensamblador
;(ensamblador de Java, pero usando NASM para codificar los bytes).
;
;http://devel.cable-modem.org/
;
;Este código es de dominio público (sin derechos de autor).
;Puedes hacer lo que desees con él.
;
;
;*****************************************************************************/


_CLASS_START:

_00000000__magic db 0xCA,0xFE,0xBA,0xBE


_00000004__minor_version dw 0x0000


_00000006__major_version db 0x00,0x33


_00000008__constant_pool_count db 0,29+1

    _0000000A__cp_info_0001:
                           db 0x0A    ;cp_info.tag: CONSTANT_Methodref
                           db 0,0x06  ;cp_info.info.class_index
                           db 0,0x0F  ;cp_info.info.name_and_type_index

    _0000000F__cp_info_00002:
                           db 0x09    ;cp_info.tag: CONSTANT_Fieldref
                           db 0,0x10  ;cp_info.info.class_index
                           db 0,0x11  ;cp_info.info.name_and_type_index

    _00000014__cp_info_0003:
                           db 0x08    ;cp_info.tag: CONSTANT_String
                           db 0,0x12  ;cp_info.info.string_index

    _00000017__cp_info_0004:
                           db 0x0A    ;cp_info.tag: CONSTANT_Methodref
                           db 0,0x13  ;cp_info.info.class_index
                           db 0,0x14  ;cp_info.info.name_and_type_index

    _0000001C__cp_info_0005:
                           db 0x07    ;cp_info.tag: CONSTANT_Class
                           db 0,0x15  ;cp_info.info.name_index

    _0000001F__cp_info_0006:
                           db 0x07    ;cp_info.tag: CONSTANT_Class
                           db 0,0x16  ;cp_info.info.name_index

    _00000022__cp_info_0007:
                           db 0x01     ;cp_info.tag: CONSTANT_Utf8
                           db 0,0x06   ;cp_info.info.length
                           db "<init>" ;cp_info.info.bytes[length]

    _0000002B__cp_info_0008:
                           db 0x01     ;cp_info.tag: CONSTANT_Utf8
                           db 0,0x03   ;cp_info.info.length
                           db "()V"    ;cp_info.info.bytes[length]

    _00000031__cp_info_0009:
                           db 0x01     ;cp_info.tag: CONSTANT_Utf8
                           db 0,0x04   ;cp_info.info.length
                           db "Code"   ;cp_info.info.bytes[length]

    _00000038__cp_info_000A:
                           db 0x01     ;cp_info.tag: CONSTANT_Utf8
                           db 0,0x0F   ;cp_info.info.length
                           db "LineNumberTable"   ;cp_info.info.bytes[length]

    _0000004A__cp_info_000B:
                           db 0x01     ;cp_info.tag: CONSTANT_Utf8
                           db 0,0x04   ;cp_info.info.length
                           db "main"   ;cp_info.info.bytes[length]

    _00000051__cp_info_000C:
                           db 0x01     ;cp_info.tag: CONSTANT_Utf8
                           db 0,0x16   ;cp_info.info.length
                           db "([Ljava/lang/String;)V"   ;cp_info.info.bytes[length]

    _0000006A__cp_info_000D:
                           db 0x01     ;cp_info.tag: CONSTANT_Utf8
                           db 0,0x0A   ;cp_info.info.length
                           db "SourceFile"   ;cp_info.info.bytes[length]

    _00000077__cp_info_000E:
                           db 0x01     ;cp_info.tag: CONSTANT_Utf8
                           db 0,0x11   ;cp_info.info.length
                           db "EHLOWorldApp.java"   ;cp_info.info.bytes[length]

    _0000008B__cp_info_000F:
                           db 0x0C     ;cp_info.tag: CONSTANT_NameAndType
                           db 0,0x07   ;cp_info.info.name_index
                           db 0,0x08   ;cp_info.info.descriptor_index

    _00000090__cp_info_0010:
                           db 0x07    ;cp_info.tag: CONSTANT_Class
                           db 0,0x17  ;cp_info.info.name_index

    _00000093__cp_info_0011:
                           db 0x0C     ;cp_info.tag: CONSTANT_NameAndType
                           db 0,0x18   ;cp_info.info.name_index
                           db 0,0x19   ;cp_info.info.descriptor_index

    _00000098__cp_info_0012:
                           db 0x01     ;cp_info.tag: CONSTANT_Utf8
                           db 0,0x0C   ;cp_info.info.length
                           db "Hello World."   ;cp_info.info.bytes[length]

    _000000A6__cp_info_0013:
                           db 0x07    ;cp_info.tag: CONSTANT_Class
                           db 0,0x1A  ;cp_info.info.name_index

    _000000A9__cp_info_0014:
                           db 0x0C     ;cp_info.tag: CONSTANT_NameAndType
                           db 0,0x1B   ;cp_info.info.name_index
                           db 0,0x1C   ;cp_info.info.descriptor_index

    _000000AE__cp_info_0015:
                           db 0x01     ;cp_info.tag: CONSTANT_Utf8
                           db 0,0x0C   ;cp_info.info.length
                           db "EHLOWorldApp"   ;cp_info.info.bytes[length]

    _000000BD__cp_info_0016:
                           db 0x01     ;cp_info.tag: CONSTANT_Utf8
                           db 0,0x10   ;cp_info.info.length
                           db "java/lang/Object"   ;cp_info.info.bytes[length]

    _000000D0__cp_info_0017:
                           db 0x01     ;cp_info.tag: CONSTANT_Utf8
                           db 0,0x10   ;cp_info.info.length
                           db "java/lang/System"   ;cp_info.info.bytes[length]

    _000000E3__cp_info_0018:
                           db 0x01     ;cp_info.tag: CONSTANT_Utf8
                           db 0,0x03   ;cp_info.info.length
                           db "out"   ;cp_info.info.bytes[length]

    _000000E9__cp_info_0019:
                           db 0x01     ;cp_info.tag: CONSTANT_Utf8
                           db 0,0x15   ;cp_info.info.length
                           db "Ljava/io/PrintStream;"   ;cp_info.info.bytes[length]

    _00000101__cp_info_001A:
                           db 0x01     ;cp_info.tag: CONSTANT_Utf8
                           db 0,0x13   ;cp_info.info.length
                           db "java/io/PrintStream"   ;cp_info.info.bytes[length]

    _00000117__cp_info_001B:
                           db 0x01     ;cp_info.tag: CONSTANT_Utf8
                           db 0,0x07   ;cp_info.info.length
                           db "println"   ;cp_info.info.bytes[length]

    _00000121__cp_info_001C:
                           db 0x01     ;cp_info.tag: CONSTANT_Utf8
                           db 0,0x15   ;cp_info.info.length
                           db "(Ljava/lang/String;)V"   ;cp_info.info.bytes[length]

                        __1D:
                           db 0x08    ;cp_info.tag: CONSTANT_String
                           db 0,0x12  ;cp_info.info.string_index




_00000139__access_flags:
                       db 0x00,0x20


_0000013B__this_class:
                       db 0x00,0x05

_0000013D__super_class:
                       db 0x00,0x06

_0000013F__interfaces_count:
                       db 0x00,0x00

;interfaces ------- no interfaces


_00000141__fields_count:
                       db 0x00,0x00


;field_info ------- no fields


_00000143__methods_count:
                       db 0x00,0x02


        _00000145__method_info_0001:
                               db 0x00,0x00     ;access_flags
                               db 0x00,0x07     ;name_index
                               db 0x00,0x08     ;descriptor_index
                               db 0x00,0x01     ;attributes_count
                                   db 0x00,0x09   ;code_attribute/attribute_info[0].attribute_name_index
                                   db 0x00,0x00,0x00,(0x1D)   ;code_attribute/attribute_info[0].attribute_length

                                   db 0X00,0X01       ;code_attribute.max_stack
                                   db 0X00,0X01       ;code_attribute.max_locals
                                   db 0X00,0X00,0X00,0X05   ;code_attribute.code_length

                                      ;INIT: Instructions
                                      ;INIT: Instructions
                                      ;INIT: Instructions
                                      ;INIT: Instructions

                                        db 0X2A         ;aload_0

                                        db 0XB7         ;invokespecial #1
                                        db 0X00
                                        db 0X01

                                        db 0XB1         ;return

                                      ;END: Instructions
                                      ;END: Instructions
                                      ;END: Instructions
                                      ;END: Instructions



                                   db 0X00,0X00    ;code_attribute.exception_table_length


                                   db 0X00,0x01    ;code_attribute.attributes_count       ;1

                                       db 0X00,0X0A             ;LineNumberTable_attribute/attribute_info.attribute_name_index
                                       db 0X00,0X00,0X00,0X06   ;LineNumberTable_attribute/attribute_info.attribute_length
                                           db 0X00,0X01       ;LineNumberTable_attribute.line_number_table_length
                                               db 0X00,0X00       ;line_number_table[0].start_pc
                                               db 0X00,0X05       ;line_number_table[0].line_number


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        _00000170__method_info_0002:
                               db 0x00,0x09     ;access_flags
                               db 0x00,0x0B     ;name_index
                               db 0x00,0x0C     ;descriptor_index
                               db 0x00,0x01     ;attributes_count
                                   db 0x00,0x09   ;code_atribute/attribute_info[0].attribute_name_index
                                   db 0x00,0x00,0x00,(0x25)   ;code_atribute/attribute_info[0].attribute_length
x17E:
                                   db 0x00,0x02      ;code_attribute.max_stack
                                   db 0x00,0x01      ;code_attribute.max_locals
                                   db 0x00,0x00,0x00,(0x09)  ;code_attribute.code_length

                                      ;INIT: Instructions
                                      ;INIT: Instructions
                                      ;INIT: Instructions
                                      ;INIT: Instructions


                                        db 0xB2      ;getstatic #2
                                        db 0x00
                                        db 0x02

                                        db 0x12      ;ldc #3
                                        db 0x1D

                                        db 0xB6      ;invokevirtual #4
                                        db 0x00
                                        db 0x04

                                        db 0xB1      ;return

                                      ;END: Instructions
                                      ;END: Instructions
                                      ;END: Instructions
                                      ;END: Instructions

                                   db 0x00,0x00      ;code_attribute.exception_table_length


                                   db 0x00,0x01      ;code_attribute.attributes_count    ;1

                                       db 0x00,0x0A              ;LineNumberTable_attribute/attrbute_info.attribute_name_index
                                       db 0x00,0x00,0x00,0x0A    ;LineNumberTable_attribute/attribute_info.attribute_length
                                             db 0x00,0x02       ;LineNumberTable_attribute.line_number_table_length
                                                 db 0x00,0x00       ;line_number_table[0].start_pc
                                                 db 0x00,0x07       ;line_number_table[0].line_number

                                                 db 0x00,0x08       ;line_number_table[1].start_pc
                                                 db 0x00,0x08       ;line_number_table[1].line_number



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
f_000001A3__attributes_count db 0x00,0x01     ;attributes_count           ;1
                                db 0x00,0x0D   ;SourceFile_attribute/attribute_info[0].attribute_name_index
                                db 0x00,0x00,0x00,0x02   ;SourceFile_attribute/attribute_info[0].attribute_length


                                db 0x00,0x0E         ;SourceFile_attribute.sourcefile_index



Y el código equivalente en Java normal:

Código:
class EHLOWorldApp
{
 public static void main(String[] args)
 {
  System.out.println("Hello World.");
 }
}



Planeo poco a poco documentar y explicar lo que está pasando, aunque ya que he comentado prácticamente todas las líneas en ensamblador, obviamente entiendo lo que está pasando.

Aunque necesito formalizar las explicaciones, porque voy a necesitarlo cuando trate escribir un ensamblador especial para Java y cuando quiera implementar un compilador de un lenguaje que no sea Java, pero que produzca programas para Java.


------------------------------------------------------
------------------------------------------------------
------------------------------------------------------
------------------------------------------------------




Referencias

Seguir las especificaciones es relativamente fácil para quienes, como yo, están acostumbrados a examinar de forma permanente la estructura de todos los archivos en su computadora, a hacer encajar exactamente cada pieza de un programa en ensamblador (lo que permite encontrar mucho más rápidamente la causa de errores causados por dos o más valores interdependientes) y a pensar en términos de cómo las especificaciones combinan los datos requeridos para una tarea en estructuras de todo tipo (y teniendo en mente qué pudieron haber estado pensando los desarrolladores de dichos estándares para hacer las cosas de la forma en que las hicieron de entre muchos diseños posibles e incluso mucho más simplificados).

Como dije, una de las intenciones principales de todo esto es eventualmente poder escribir programas de Java con lenguajes "normales", como C, Visual Basic, Pascal, etc.

Pero para eso se necesita tener gran experticia en el ensamblador de Java, y en la estructura de bajo nivel del lenguaje, las clases, y todos los demás aspectos de la máquina virtual de Java, para poder crear equivalentes para hacer que de un lenguaje no oficial se pueda producir bytecode apropiado y totalmente correcto.

Esta es la lista de lo que hay que empezar a leer, y no hay que olvidar tampoco las referencias de las diferentes APIs, y también el tutorial de Java, que sería extremadamente interesante "remasterizar" en su versión en ensamblador Java, para comprender cada detalle de lo que contiene y hacer posible que se convierta en un libro de alto nivel capaz de volver a un programador en un experto absoluto en Java, ya sea programando en alto nivel o en el nivel más bajo posible:


Especificaciones de bajo nivel de Java

El capítulo 4 habla específicamente del formato de los archivos .class


Wikipedia: Formato de los archivos .class

Wikipedia: Resumen del bytecode de Java

Wikipedia: Resumen del conjunto de instrucciones de Java


También vale la pena mencionar el comando básico del desensamblador del JDK:

javap -c EHLOWorldApp.class
23  Programación / Programación General / Programación por Diversión: Núcleo Básico (2012-06-21) en: 22 Junio 2012, 05:49 am
Como había mencionado hace un par de semanas, quería implementar un programa de bajo nivel que fuera simple pero a la vez útil, y para eso era necesario que fuera capaz de correr programas externos.

Por ahora, solamente pueden leerse archivos de una disquetera interna, no una USB.

Poco a poco voy a explicar e indexar la información de cómo hace cada cosa, pero a la vista del usuario este programa es como una versión Alpha de una consola de MS-DOS en su primera versión, la primera de todas, así que tiene soporte para:

- Teclado
- Pantalla de texto
- Correr programas de 32 bits desde la disquetera
- El sistema exporta funciones y variables, para que los programas externos no tengan que reimplementar la misma funcionalidad. Poco a poco voy a migrar la funcionalidad de programas externos que demuestren ser valiosos al núcleo mismo del sistema.



Lo bueno de esto es que con la capacidad de correr programas externos, se puede llevar a cabo absolutamente cualquier tarea, por ejemplo, correr un programa binario compilado en C desde Windows/Linux, que active el modo gráfico, que genere algún gráfico, y que desee guardarlo a la disquetera.

O un intérprete increíblemente simple de mi lenguaje Real C, o para entrar en estándar, un intérprete de javascript que comience con funciones como alert, el operador typeof y la declaración de variables, etc...

Con esto se hace fácil estudiar minuciosamente cualquier tarea de programación, a un grado excepcional, y todos los detalles aprendidos, usarlos para optimizar y de hecho comprender la creación de aplicaciones en sistemas ya establecidos, como Windows, Linux, Mac, etc.

Este grupo de temas que pienso poner sí va a ser lo más dinámico y prolífico que probablemente haya hecho hasta ahora en mi vida en la Web, ya que este estudio lo llevo a cabo durante todo el día, todos los días (a menos que necesite descansar), así que pido que me tengan "paciencia".

Pero lo que sí puedo prometer es que esto va a ser interesante y provechoso y poco a poco debería ser capaz de demostrar que esto es en enorme medida, inmediatamente aplicado a cualquier plataforma de computadoras.



---------------------------------------------------------------


Empiezo con el código más básico.

La pregunta es, ¿qué les parece el código fuente que he escrito hasta ahora? ¿Qué podría hacer para que sea más legible? ¿Qué idea tienen para hacer algo útil? Lo próximo que se me ocurre en lo personal es discutir programas de C con complejidad cada vez mayor, vista desde el punto de vista de un compilador, no solo compilarlos, y cómo interactúan con la máquina.

>> Muestra de un Sistema Ejecutivo Básico <<


También, empiezo inmediatamente a ver cuál es la siguiente tarea que debería llevar a cabo en lo poco que me queda de hoy.

Páginas: 1 2 [3]
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines