package zinara.code_generator;
import zinara.ast.*;
import zinara.ast.instructions.*;
import zinara.ast.expression.*;
import zinara.exceptions.InvalidArchitectureException;
import zinara.exceptions.InvalidCodeException;
import zinara.exceptions.TypeClashException;
import zinara.parser.sym;
import zinara.symtable.SymTable;
import zinara.symtable.SymValue;
import zinara.ast.type.*;
import java.io.FileWriter;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
public class Genx86{
private String[] regs;
private String[] dwordRegs;
private String[] byteRegs;
private String stackp;
private String framep;
private String stackAlig; //Alineamiento de la pila
private String global_offset;
private int n_regs;
private int next_reg;
private int bits;
private int labelCounter = 0;
private int word_size;
private BufferedWriter file;
private String save;
private String restore;
public Genx86(int bits, String fileName)
throws InvalidArchitectureException, IOException{
if (bits == 64){
regs = new String[14];
dwordRegs = new String[14];
byteRegs = new String[14];
regs[0] = "rax";
regs[1] = "rbx";
regs[2] = "rcx";
regs[3] = "rdx";
regs[4] = "rsi";
regs[5] = "rdi";
regs[6] = "r8";
regs[7] = "r9";
regs[8] = "r10";
regs[9] = "r11";
regs[10] = "r12";
regs[11] = "r13";
regs[12] = "r14";
regs[13] = "r15";
dwordRegs[0] = "eax";
dwordRegs[1] = "ebx";
dwordRegs[2] = "ecx";
dwordRegs[3] = "edx";
dwordRegs[4] = "esi";
dwordRegs[5] = "edi";
dwordRegs[6] = "r8d";
dwordRegs[7] = "r9d";
dwordRegs[8] = "r10d";
dwordRegs[9] = "r11d";
dwordRegs[10] = "r12d";
dwordRegs[11] = "r13d";
dwordRegs[12] = "r14d";
dwordRegs[13] = "r15d";
byteRegs[0] = "al";
byteRegs[1] = "bl";
byteRegs[2] = "cl";
byteRegs[3] = "dl";
byteRegs[4] = "sil";
byteRegs[5] = "dil";
byteRegs[6] = "r8b";
byteRegs[7] = "r9b";
byteRegs[8] = "r10b";
byteRegs[9] = "r11b";
byteRegs[10] = "r12b";
byteRegs[11] = "r13b";
byteRegs[12] = "r14b";
byteRegs[13] = "r15b";
stackp = "rsp";
framep = "rbp";
stackAlig = "8";
n_regs = 14;
word_size = 8;
}
else if (bits == 32){
regs = new String[6];
byteRegs = new String[6];
regs[0] = "eax";
regs[1] = "ebx";
regs[2] = "ecx";
regs[3] = "edx";
regs[4] = "esi";
regs[5] = "edi";
byteRegs[0] = "al";
byteRegs[1] = "bl";
byteRegs[2] = "cl";
byteRegs[3] = "dl";
byteRegs[4] = "sil";
byteRegs[5] = "dil";
stackp = "esp";
framep = "ebp";
stackAlig = "4";
n_regs = 6;
word_size = 4;
}
else
throw new InvalidArchitectureException(bits);
global_offset = "glob";
next_reg = 0;
this.bits = bits;
save = null;
restore = null;
file = new BufferedWriter(new FileWriter(new File(fileName)));
file.write("%include \"asm_io.inc\"\n");
if (this.bits == 64)
this.file.write("BITS 64\n");
}
public void generateProgram(Program program)
throws IOException,InvalidCodeException,TypeClashException {
// Main
program.getMain().register = 0;
program.getMain().getCode().nextInst = "halt";
program.tox86(this);
// Exits the program
writeLabel(program.getMain().getCode().nextInst);
exitSyscall(0);
writeLabel("haltNI"); //negative Index
exitSyscall(1);
writeLabel("haltOOB");//Out Of Bounds
exitSyscall(2);
closeFile();
}
public void generateHeader(SymTable symtable)
throws IOException,InvalidCodeException {
String identifier;
SymValue symValue;
// Espacio para variable globales
Iterator keyIt = symtable.keySet().iterator();
int total_size = 0;
while(keyIt.hasNext()) {
identifier = (String)keyIt.next();
symValue = symtable.getSymbol(identifier);
if (symValue.type.size() == 0){continue;}
symValue.setArea(global_offset());
symValue.setOffset("+"+Integer.toString(total_size));
total_size += symValue.type.size();
}
// Luego para variables del Main
// La tabla del main siempre queda al final de la lista de tablas hijo
SymTable mainSymTable = symtable.getSon(symtable.getSons().size()-1);
total_size = mainSymTable.reserve_mem_main(total_size,global_offset);
// .ASM HEADER
// El espacio para variables, texto de las funciones
// y el comienzo del texto del main se crean aca
write(reserve_space_str(global_offset, total_size));
write(main_header_str());
}
//Reserva tanta memoria como le pidan. data_size es la cantidad
//de bytes.
public String reserve_space_str(String label, int data_size){
String code = "";
code += "section .bss\n "+label+": resb "+data_size+"\n";
code += "section .rodata\n";
code += " int_format db \"%i\",0\n";
code += " float_format db \"%f\",0\n";
code += " string_format db \"%s\",0\n";
code += " write_format db \"w\",0\n";
return code;
}
public String main_header_str(){
return "section .text\n global main\nextern printf\nmain:\n";
}
public int stack_align(){
return Integer.parseInt(this.stackAlig);
}
public String newLabel() {
return "zn" + labelCounter++;
}
public int word_size() { return word_size; }
private String regId(int regNumber) {
return regs[regNumber % n_regs];
}
public String dwordRegId(int regNumber) {
return dwordRegs[regNumber % n_regs];
}
public String byteRegId(int regNumber) {
return byteRegs[regNumber % n_regs];
}
public String intRegName(int regNumber){
if (this.bits == 32){
return regId(regNumber);
}
else
return dwordRegId(regNumber);
}
public String realRegName(int regNumber){
return regId(regNumber);
}
public String charRegName(int regNumber){
return byteRegId(regNumber);
}
public String boolRegName(int regNumber){
if (this.bits == 32){
return regId(regNumber);
}
else
return dwordRegId(regNumber);
}
public String addrRegName(int regNumber){
return regId(regNumber);
}
public String regName(int r, Type type) throws InvalidCodeException{
if (type instanceof IntType)
return intRegName(r);
else if (type instanceof FloatType)
return realRegName(r);
else if (type instanceof BoolType)
return boolRegName(r);
else if (type instanceof CharType)
return charRegName(r);
else if ((type instanceof ListType)||
(type instanceof DictType)||
(type instanceof TupleType)||
(type instanceof VariantType)||
(type instanceof StringType))
return addrRegName(r);
else
throw new InvalidCodeException("No se tienen registros para el tipo "+type);
}
public void write(String thing) throws IOException{
file.write(thing);
}
public void writeLabel(String label) throws IOException {
file.write(label + ":\n");
}
public void closeFile() throws IOException{
file.close();
}
public String stack_pointer(){
return this.stackp;
}
public String frame_pointer(){
return this.framep;
}
public String global_offset(){
return global_offset;
}
public String get_reg(int reg){
return regs[reg%n_regs];
}
//Push
public String push (String thing){
String code = "";
if (this.bits == 32)
return "push "+thing+"\n";
else{
code += sub("rsp",stackAlig);
code += mov("[rsp]",thing);
return code;
}
}
//Push con resta arbitraria
public String push (String thing, int size){
String code = "";
code += sub(this.stackp,Integer.toString(size));
code += mov("["+this.stackp+"]",thing);
return code;
}
//Push de 1 byte (word)
public String pushb (String thing){
String code = "";
code += sub(this.stackp,"1");
code += mov("["+this.stackp+"]",thing,"byte");
return code;
}
//Push de 32 bits (dword)
public String pushw (String thing){
String code = "";
if (this.bits == 32)
return "push "+thing+"\n";
else{
code += sub("rsp","4");
code += mov("[rsp]",thing,"dword");
return code;
}
}
//Push de 64 bits (quad-word)
public String pushq (String thing) throws InvalidCodeException{
String code = "";
if (this.bits == 64){
code += sub("rsp",stackAlig);
code += mov("[rsp]",thing,"qword");
return code;
}
else{
throw new InvalidCodeException("pushq en 32 bits");
}
}
// Pop, la cantidad de bits es la misma
//que la del destino (thing). Si nasm no
//puede deducir la cantidad de bits,
//va a dar error. En ese caso usar el otro pop.
//(Esta funcion esta sobrecargada)
public String pop (String thing){
String code = "";
if (this.bits == 32)
return "pop "+thing+"\n";
else{
code += mov(thing,"[rsp]");
code += add("rsp",this.stackAlig);
return code;
}
}
// Pop que especifica la cantidad de bits
//que se deben mover. Si los bits son vacios
//nasm deduce cuantos se deben mover, si puede.
// Independiente de la arquitectura
public String pop (String thing, String size_mod)
throws InvalidCodeException{
String size;
if (size_mod.compareTo("qword")==0){
if (this.bits != 64)
throw new InvalidCodeException("pop de un qword en 32 bits");
size = "8";
}
else if (size_mod.compareTo("dword")==0){
size = "4";
}
else if (size_mod.compareTo("word")==0){
size = "2";
}
else if (size_mod.compareTo("byte")==0){
size = "1";
}
else
throw new InvalidCodeException("modificador de tamano invalido");
String code = "";
code += mov(thing,"["+this.stackp+"]",size_mod);
code += add(this.stackp,size);
return code;
}
public String push(String t, Type type) throws InvalidCodeException{
if (type instanceof IntType)
return pushInt(t);
else if (type instanceof FloatType)
return pushReal(t);
else if (type instanceof BoolType)
return pushInt(t);
else if (type instanceof CharType)
return pushChar(t);
else if ((type instanceof ListType)||
(type instanceof DictType)||
(type instanceof TupleType)||
(type instanceof StringType))
return pushAddr(t);
else
throw new InvalidCodeException("No se tiene push para el tipo "+type);
}
public String pushInt (String in){
if (this.bits == 32)
return push(in);
else
return pushw(in);
}
public String pushReal (String real) throws InvalidCodeException{
if (this.bits == 32)
return pushFloat(real);
else
return pushDouble(real);
}
public String pushFloat (String flo){
if (this.bits == 32)
return push(flo);
else
return pushw(flo);
}
public String pushDouble (String dou) throws InvalidCodeException{
if (this.bits == 64)
return push(dou);
else{
throw new InvalidCodeException("pushDouble en 32 bits");
}
}
public String pushChar (String ch){
return pushb(ch);
}
public String pushAddr (String addr){
return push(addr);
}
public String pop(String t, Type type) throws InvalidCodeException{
if (type instanceof IntType)
return popInt(t);
else if (type instanceof FloatType)
return popReal(t);
else if (type instanceof BoolType)
return popInt(t);
else if (type instanceof CharType)
return popChar(t);
else if ((type instanceof ListType)||
(type instanceof DictType)||
(type instanceof TupleType)||
(type instanceof StringType))
return popAddr(t);
else
throw new InvalidCodeException("No se tiene pop para el tipo "+type);
}
public String popInt (String in)
throws InvalidCodeException{
return pop(in,"dword");
}
public String popReal (String real)
throws InvalidCodeException{
if (this.bits == 32)
return popFloat(real);
else
return popDouble(real);
}
public String popFloat (String flo)
throws InvalidCodeException{
return pop(flo,"dword");
}
public String popDouble (String dou)
throws InvalidCodeException{
if (this.bits == 64)
return pop(dou,"qword");
else{
throw new InvalidCodeException("popDouble en 32 bits");
}
}
public String popChar (String ch)
throws InvalidCodeException{
return pop(ch,"byte");
}
public String popAddr (String addr)
throws InvalidCodeException{
if (this.bits == 32)
return pop(addr,"dword");
else
return pop(addr,"qword");
}
// Usando este mov, nasm deducira la cantidad de
//bytes a mover a partir del contexto.
public String mov(String dst, String orig){
return "mov "+dst+","+orig+"\n";
}
// Usando este mov, se le especifica explicitamente
//a nasm la cantidad de bytes (byte,word,dword o qword).
private String mov(String dst, String orig, String size_mod){
return "mov "+size_mod+" "+dst+","+orig+"\n";
}
public String movInt(String dst, String orig){
return mov(dst,orig,"dword");
}
public String movReal(String dst, String orig){
if (this.bits == 32)
return mov(dst,orig,"dword");
else
return mov(dst,orig,"qword");
}
public String movBool(String dst, String orig){
return mov(dst,orig,"dword");
}
public String movChar(String dst, String orig){
return mov(dst,orig,"byte");
}
public String movAddr(String dst, String orig){
if (this.bits == 32)
return mov(dst,orig,"dword");
else
return mov(dst,orig,"qword");
}
public String mov(String dst, String orig, Type type)
throws InvalidCodeException{
if (type instanceof IntType)
return movInt(dst,orig);
else if (type instanceof FloatType)
return movReal(dst,orig);
else if (type instanceof BoolType)
return movBool(dst,orig);
else if (type instanceof CharType)
return movChar(dst,orig);
else if ((type instanceof ListType)||
(type instanceof DictType)||
(type instanceof TupleType)||
(type instanceof StringType))
return movAddr(dst,orig);
else
throw new InvalidCodeException("No se tiene mov para el tipo "+type);
}
public String fst(String dst, String size){
return "fst "+size+" "+dst+"\n";
}
public String fstp(String dst, String size){
return "fstp "+size+" "+dst+"\n";
}
public String fld(String orig, String size){
return "fld "+size+" "+orig+"\n";
}
public String fst(String dst){
if (this.bits == 32)
return "fst dword"+dst+"\n";
else
return "fst qword"+dst+"\n";
}
public String fstp(String dst){
if (this.bits == 32)
return "fstp dword"+dst+"\n";
else
return "fstp qword"+dst+"\n";
}
public String fld(String orig){
if (this.bits == 32)
return "fld dword"+orig+"\n";
else
return "fld qword"+orig+"\n";
}
public String fist(String dst){
if (this.bits == 32)
return "fist dword"+dst+"\n";
else
return "fist qword"+dst+"\n";
}
public String fild(String orig){
if (this.bits == 32)
return "fild dword"+orig+"\n";
else
return "fild qword"+orig+"\n";
}
public String fxch(){
return "fxch\n";
}
public String fxchR(String st){
return "fxch "+st+"\n";
}
public String ffree(String st){
return "ffree "+st+"\n";
}
public String fninit(){
return "fninit\n";
}
//Suma de enteros
public String add(String dst, String op2){
return "add "+dst+","+op2+"\n";
}
//Resta de enteros
public String sub(String dst, String op2){
return "sub "+dst+","+op2+"\n";
}
//Multiplicacion de enteros
public String imul(String dst, String op2){
return "imul "+dst+","+op2+"\n";
}
//Division de enteros, el resultado queda en dividend
public String idiv(String dividend, String diviser)
throws InvalidCodeException{
String code = "";
String ax = regId(0);
String bx = regId(1);
String dx = regId(3);
code += push(ax); //Parte baja del dividendo
code += push(bx); //Divisor
code += push(dx); //Parte alta del dividendo
//Aqui pongo los argumentos en los registros
code += pushInt(dividend);
code += pushInt(diviser);
code += popInt("ebx");
code += popInt("eax");
code += mov(dx,"0h");
//Limpio la parte alta porque no se va a usar
code += "idiv ebx\n";
code += pop(dx);//Restauro registros
code += pop(bx);//Restauro registros
//If en caso de que el registro donde debe quedar la division
//esa el mismo eax, no lo puedo sobreescribir
if (dividend.compareTo("eax") == 0)
code += add(this.stackp,this.stackAlig);
else{
code += mov(dividend,"eax");
code += pop(ax);
}
return code;
}
//Modulo de enteros, el resultado queda en dividend
public String imod(String dividend, String diviser){
String code = "";
code += pushw("eax"); //Parte baja del dividendo
code += pushw("ebx"); //Divisor
code += pushw("edx"); //Parte alta del dividendo
//Aqui pongo los argumentos en los registros
code += pushw(dividend);
code += pushw(diviser);
code += pop("ebx");
code += pop("eax");
code += mov("edx","0h","dword");
//Limpio la parte alta porque no se va a usar
code += "idiv ebx\n";
code += pop("edx");//Restauro registros
code += pop("ebx");//Restauro registros
//If en caso de que el registro donde debe quedar la division
//esa el mismo eax, no lo puedo sobreescribir
if (dividend.compareTo("edx") == 0)
code += add(this.stackp,this.stackAlig);
else{
code += mov(dividend,"edx");
code += pop("edx");
}
return code;
}
//Suma de flotantes
//Para que esto funcione dst y op2 deben ser registros
public String fadd(String dst, String op2){
String code = "";
String size;
if (this.bits == 32)
size = "dword";
else
size = "qword";
code += mov("["+this.stackp+"]",dst);
code += fld("["+this.stackp+"]",size);
code += mov("["+this.stackp+"]",op2);
code += fld("["+this.stackp+"]",size);
code += "fadd st0,st1\n";
code += fstp("["+this.stackp+"]",size);
code += mov(dst,"["+this.stackp+"]");
code += fninit();
return code;
}
//Resta de flotantes
public String fsub(String dst, String op2){
String code = "";
String size;
if (this.bits == 32)
size = "dword";
else
size = "qword";
code += mov("["+this.stackp+"]",dst);
code += fld("["+this.stackp+"]",size);
code += mov("["+this.stackp+"]",op2);
code += fld("["+this.stackp+"]",size);
code += "fsub st0,st1\n";
code += fstp("["+this.stackp+"]",size);
code += mov(dst,"["+this.stackp+"]");
code += fninit();
return code;
}
//Multiplicacion de flotantes
public String fmul(String dst, String op2){
String code = "";
String size;
if (this.bits == 32)
size = "dword";
else
size = "qword";
code += mov("["+this.stackp+"]",dst);
code += fld("["+this.stackp+"]",size);
code += mov("["+this.stackp+"]",op2);
code += fld("["+this.stackp+"]",size);
code += "fmul st0,st1\n";
code += fstp("["+this.stackp+"]",size);
code += mov(dst,"["+this.stackp+"]");
code += fninit();
return code;
}
//Multiplicacion de flotantes
public String fdiv(String dst, String op2){
String code = "";
String size;
if (this.bits == 32)
size = "dword";
else
size = "qword";
code += mov("["+this.stackp+"]",dst);
code += fld("["+this.stackp+"]",size);
code += mov("["+this.stackp+"]",op2);
code += fld("["+this.stackp+"]",size);
code += "fdiv st0,st1\n";
code += fstp("["+this.stackp+"]",size);
code += mov(dst,"["+this.stackp+"]");
code += fninit();
return code;
}
public String and(String a, String b){
return "and "+a+","+b+"\n";
}
public String or(String a, String b){
return "or "+a+","+b+"\n";
}
public String xor(String a, String b){
return "xor "+a+","+b+"\n";
}
public String fcomi(){
return "fcomi st0, st1\n";
}
public String ficom(String integer,String size){
return "ficom "+size+" "+integer+"\n";
}
public String cmp(String a, String b){
return "cmp "+a+","+b+"\n";
}
public String compare(String a, String b, Type at, Type bt)
throws InvalidCodeException{
String code = "";
String size;
if (this.bits == 32)
size = "dword";
else
size = "qword";
if (at instanceof IntType){
if (bt instanceof IntType)
return cmp(a,b);
}
else if (at instanceof FloatType){
if (bt instanceof FloatType){
code += fninit();
code += pushReal(a);
code += fld("["+stackp+"]",size);
code += movReal("["+stackp+"]",b);
code += fld("["+stackp+"]",size);
code += popReal(b);
code += fcomi();
return code;
}
}
else if ((at instanceof BoolType) && (bt instanceof BoolType)) {
return cmp(a,b);
//System.out.println(" -> " + a + " ; " + b);
}
else
throw new InvalidCodeException("No se pueden comparar "+
at+
"contra "+
bt);
return "";
}
public String jump(String label){
return "jmp " + label + "\n";
}
public String jz(String label){
return "jz "+label+"\n";
}
public String jnz(String label){
return "jnz "+label+"\n";
}
public String je(String label){
return "je "+label+"\n";
}
public String jne(String label){
return "jne "+label+"\n";
}
public String jg(String label){
return "jg "+label+"\n";
}
public String jge(String label){
return "jge "+label+"\n";
}
public String jl(String label){
return "jl "+label+"\n";
}
public String jle(String label){
return "jle "+label+"\n";
}
public String call(String label){
return "call "+label+"\n";
}
public String ret(){
return "ret\n";
}
public String syscall(){
if (this.bits == 32)
return "int 80h\n";
else
return "syscall\n";
}
public String save(int reg) throws InvalidCodeException{
if (reg > n_regs)
if (this.bits == 32)
return pushw(regId(reg));
else
return pushq(regId(reg));
else
return "";
}
public String restore(int reg) throws InvalidCodeException{
if (reg > n_regs)
if (this.bits == 32)
return pop(regId(reg),"dword");
else
return pop(regId(reg),"qword");
else
return "";
}
public String save_print_regs() throws InvalidCodeException{
String code = "";
if (this.bits == 32){
code += pushw("eax");//Codigo del syscall
code += pushw("ebx");//Descriptor
code += pushw("ecx");//Direccion del string
code += pushw("edx");//Cantidad a imprimir
}
else{
code += pushq("rax");//Codigo del syscall
code += pushq("rdi");//Descriptor
code += pushq("rsi");//Direccion del string
code += pushq("rdx");//Cantidad a imprimir
code += pushq("rcx");//Registro que destruye el kernel
code += pushq("r11");//Registro que destruye el kernel
}
return code;
}
public String restore_print_regs(){
String code = "";
if (this.bits == 32){
code += pop("edx");
code += pop("ecx");
code += pop("ebx");
code += pop("eax");
}
else{
code += pop("r11");
code += pop("rcx");
code += pop("rdx");
code += pop("rsi");
code += pop("rdi");
code += pop("rax");
}
return code;
}
//El llamado guarda los registros rbx y r12-r15 para x86_64
//El llamado guarda los registros eax,ecx y edx para x86
public String save_regs_callee()
throws InvalidCodeException{
String code = "";
if (this.bits == 32){
//eax
code += push(regs[0]);
//ecx
code += push(regs[2]);
//edx
code += push(regs[3]);
}
else{
//rbx
code += push(regs[1]);
//r12 - r15
for(int i=10; i<=13 ; ++i){
code += push(regs[i]);
}
}
return code;
}
//El llamado guarda los registros rbx y r12-r15 para x86_64
//El llamado guarda los registros eax,ecx y edx para x86
public String restore_regs_callee()
throws InvalidCodeException{
String code = "";
if (this.bits == 32){
//edx
code += pop(regs[3]);
//ecx
code += pop(regs[2]);
//eax
code += pop(regs[0]);
}
else{
//r12 - r15
for(int i=13; i >= 10; --i){
code += pop(regs[i]);
}
//rbx
code += pop(regs[1]);
}
return code;
}
/*El llamador guarda los registros rax, rcx, rdx, rsi, rdi
y r8-r11 para x86_64.*/
//El llamador solo guarda los registros ebx, esi y edi para x86
public String save_regs_caller(int reg)
throws InvalidCodeException{
String code = "";
if (this.bits == 32){
//ebx
if (reg > 1)
code += push(regs[1]);
//esi
if (reg > 4)
code += push(regs[4]);
//edi
if (reg > 5)
code += push(regs[5]);
}
else{
//rax
if (reg > 0)
code += push(regs[0]);
//rcx - r11
for(int i=2; i<reg && i<=9 ; ++i){
code += push(regs[i]);
}
}
return code;
}
/*El llamador guarda los registros rax, rcx, rdx, rsi, rdi
y r8-r11 para x86_64.*/
//El llamador solo guarda los registros ebx, esi y edi para x86
public String restore_regs_caller(int reg)
throws InvalidCodeException{
String code = "";
if (this.bits == 32){
//ebx
if (reg > 5)
code += pop(regs[5]);
//esi
if (reg > 4)
code += pop(regs[4]);
//edi
if (reg > 1)
code += pop(regs[1]);
}
else{
//rcx - r11
for(int i=min(9,reg); i >= 2; --i){
code += pop(regs[i]);
}
//rax
if (reg > 0)
code += pop(regs[0]);
}
return code;
}
//El addr, si es un label, debe venir sin corchetes
public String setup_print(String addr, String desc, String bytes){
String code = "";
if (this.bits == 32){
code += mov("eax","4"); //Codigo de sys_write 32 bits
code += mov("ebx",desc); //Descriptor a donde escribir (1=stdout)
code += mov("ecx",addr); //Direccion donde comienza el valor a imprimir
code += mov("edx",bytes); //Cantidad de bytes que se van a imprimir
}
else{
code += mov("rax","1"); //Codigo de sys_write 64 bits
code += mov("rdi",desc); //Descriptor a donde escribir (1=stdout)
code += mov("rsi",addr); //Direccion donde comienza el valor a imprimir
code += mov("rdx",bytes); //Cantidad de bytes que se van a imprimir
}
return code;
}
public void exitSyscall(int exit_code) throws IOException {
String code = "\n";
String e_code = Integer.toString(exit_code);
if (this.bits == 64){
code += mov("rax","60");
code += mov("rdi",e_code);
}
else{
code += mov("eax","1");
code += mov("ebx",e_code);
}
code += syscall();
write(code);
}
public String toASCII(char C){
return DataTranslator.toASCII(C);
}
public String toReal(double F){
if (bits == 32)
return DataTranslator.toReal((float)F);
else
return DataTranslator.toReal(F);
}
public String toReal(float F){
return DataTranslator.toReal(F);
}
public int min(int a,int b){
if (a>b)
return b;
else
return a;
}
}