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
;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.");
}
}
{
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