代码拉取完成,页面将自动刷新
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "tree.h"
#include "asm.h"
extern FILE * yyout;
char *Table=" ";
char AutoRegSelect = 0;
Num8 XmmSelect = 0;
char *GetOpName(OpCode opc){
switch(opc){
case AS_MOV: return "mov";
case AS_LEA: return "lea";
case AS_ADD: return "add";
case AS_SUB: return "sub";
case AS_MUL: return "mul";
case AS_DIV: return "div";
case AS_PUSH: return "push";
case AS_POP: return "pop";
case AS_FLD: return "fld";
case AS_FSTP: return "fstp";
}
}
char *GetMemSize(MemSize size){
switch(size){
case MEM_BYTE: return "BYTE ";
case MEM_WORD: return "WORD ";
case MEM_DWORD: return "DWORD ";
case MEM_QWORD: return "QWORD ";
}
}
char *GetRegName(Register reg){
switch(reg){
case R_AL: return "al";
case R_AX: return "ax";
case R_EAX: return "eax";
case R_RAX: return "rax";
case R_BL: return "bl";
case R_BX: return "bx";
case R_EBX: return "ebx";
case R_RBX: return "rbx";
case R_CL: return "cl";
case R_CX: return "cx";
case R_ECX: return "ecx";
case R_RCX: return "rcx";
case R_DL: return "dl";
case R_DX: return "dx";
case R_EDX: return "edx";
case R_RDX: return "rdx";
case R_SI: return "si";
case R_ESI: return "esi";
case R_RSI: return "rsi";
case R_DI: return "di";
case R_EDI: return "edi";
case R_RDI: return "rdi";
case R_SP: return "sp";
case R_ESP: return "esp";
case R_RSP: return "rsp";
case R_BP: return "bp";
case R_EBP: return "ebp";
case R_RBP: return "rbp";
case R_XMM: return "xmm";
case R_R8B: return "r8b";
case R_R8W: return "r8w";
case R_R8D: return "r8d";
case R_R8: return "r8";
case R_R9B: return "r9b";
case R_R9W: return "r9w";
case R_R9D: return "r9d";
case R_R9: return "r9";
}
}
char isNoSign(DataType t){
if(t==DATA_TYPE_STRING) return 1;
return 0;
}
char isReg8(Register r){
if(r==R_AL|| r==R_BL|| r==R_CL|| r==R_DL
|| r==R_R8B|| r==R_R9B) return 1;
return 0;
}
char isReg16(Register r){
if(r==R_AX||r==R_BX|| r==R_CX|| r==R_DX
|| r==R_SI|| r==R_DI|| r==R_SP|| r==R_BP
|| r==R_R8W|| r==R_R9W) return 1;
return 0;
}
char isReg32(Register r){
if(r==R_EAX|| r==R_EBX|| r==R_ECX|| r==R_EDX
|| r==R_ESI|| r==R_EDI|| r==R_ESP|| r==R_EBP
|| r==R_R8D|| r==R_R9D) return 1;
return 0;
}
char isReg64(Register r){
if(r==R_RAX|| r==R_RBX|| r==R_RCX|| r==R_RDX
|| r==R_RSI|| r==R_RDI|| r==R_RSP|| r==R_RBP
|| r==R_R8 || r==R_R9 ) return 1;
return 0;
}
char GeiBitSize(Register r){
if(isReg8(r)) return 8;
else if(isReg16(r)) return 16;
else if(isReg32(r)) return 32;
else if(isReg64(r)) return 64;
}
char *GetObj(_OBJ_ *obj, GetObjExtendOPT e_opt){
if(!obj) return " ";
if(obj->type == OBJ_REG){
char *size=GetMemSize(obj->Reg.size);
char *name=GetRegName(obj->Reg.name);
static char ret[8];
if(obj->Reg.name == R_XMM){
sprintf(ret, "%s%lld", name, obj->Imm.n);
return ret;
}
if(size){
sprintf(ret, "%s%s", size, name);
return ret;
}
return name;
}else if(obj->type == OBJ_IMM){
static char num[8];
sprintf(num, "%lld", obj->Imm.n);
return num;
}else if(obj->type == OBJ_MEM){
char *size=GetMemSize(obj->Reg.size);
char *name=GetRegName(obj->Reg.name);
static char ret[10];
if(e_opt == EP_NOMemSize)
sprintf(ret, "[%s-%lld]", name, obj->Imm.n);
else
sprintf(ret, "%s[%s-%lld]",size, name, obj->Imm.n);
return ret;
}else if(obj->type == OBJ_STR){
return obj->Str.name;
}
}
void ProduceAsm(Command *cmd){
if(!cmd->source){
// cmd target
fprintf(yyout, "%s%s %s\n", Table, GetOpName(cmd->op), GetObj(cmd->target,EP_NULL));
}else
{
//cmd target, source
fprintf(yyout, "%s%s %s, %s\n", Table, GetOpName(cmd->op), GetObj(cmd->target,EP_NULL), GetObj(cmd->source,EP_NULL) );
}
}
char * ProduceFloatAsm(Num8 n, _OBJ_ *obj){
static char info[8];
if(obj->type == OBJ_STR){ //标号
sprintf(info, "%s[%s%lld]", GetMemSize(obj->Str.size), obj->Str.name, n);
}else{ //内存
char *size=GetMemSize(obj->Reg.size);
char *name=GetRegName(obj->Reg.name);
sprintf(info, "%s[%lld+%s]", size,n,name);
}
return info;
}
void _mov(_OBJ_ *target, _OBJ_ *source){
Command *cmd = (Command *)malloc(sizeof(Command));
cmd->op = AS_MOV;
cmd->target = target;
cmd->source = source;
ProduceAsm(cmd);
}
DataType _movsx(_OBJ_ *target, _OBJ_ *source){
char t_size = GeiBitSize(target->Reg.name);
char s_size = GeiBitSize(source->Reg.name);
// printf("t_size: %d, s_size:%d \n", t_size, s_size);
if(s_size>=32 && t_size<=s_size) return source->dt;
if(t_size==8){
target->Reg.name = (Register)(target->Reg.name+2);
target->dt = (DataType)(target->dt+2);
}else if(t_size==16){
target->Reg.name = (Register)(target->Reg.name+1);
target->dt = (DataType)(target->dt+1);
}
fprintf(yyout, "%smovsx %s, %s\n", Table, GetObj(target,EP_NULL), GetObj(source,EP_NULL) );
return target->dt;
}
void _add(_OBJ_ *target, _OBJ_ *source){
Command *cmd = (Command *)malloc(sizeof(Command));
cmd->op = AS_ADD;
cmd->target = target;
cmd->source = source;
ProduceAsm(cmd);
}
void _sub(_OBJ_ *target, _OBJ_ *source){
Command *cmd = (Command *)malloc(sizeof(Command));
cmd->op = AS_SUB;
cmd->target = target;
cmd->source = source;
ProduceAsm(cmd);
}
void _imul(_OBJ_ *target, _OBJ_ *source){
//检测source是否是纯数字, 如果不是需要mov到dx
if(source->type == OBJ_IMM){
_mov(dx(target->dt), source);
}
fprintf(yyout, "%simul %s\n", Table, GetObj( dx(target->dt), EP_NULL) );
fprintf(yyout, "%smov DWORD [rsp-8], eax\n", Table);
fprintf(yyout, "%smov DWORD [rsp-4], edx\n", Table);
fprintf(yyout, "%smov rax, QWORD [rsp-8]\n", Table);
}
void _idiv(_OBJ_ *target, _OBJ_ *source){
//fprintf(yyout, "%scdq\n", Table);
// CBW、CWD、CDQ 的作用: 低位符号位扩展到高位
//al->ah, ax->dx, eax->edx
//除了8位, 16 32 64都是(dx:ax|edx:eax|rdx:rax)为被除数
if(source->type == OBJ_IMM){
_mov(bx(target->dt), source);
}else{
_mov(bx(target->dt), dx(target->dt));
}
//整数除法最大64位,使用低位就行了
//高位永远是0
//只取商,不要余数
_mov(dx(DATA_TYPE_NUMBER_8), imm(0));
// 除数在bx或立即数
fprintf(yyout, "%sidiv %s\n", Table, GetObj( bx(target->dt), EP_NULL) );
}
void _push(_OBJ_ *target){
Command *cmd = (Command *)malloc(sizeof(Command));
cmd->op = AS_PUSH;
cmd->target = target;
ProduceAsm(cmd);
}
void _pop(_OBJ_ *target){
Command *cmd = (Command *)malloc(sizeof(Command));
cmd->op = AS_POP;
cmd->target = target;
ProduceAsm(cmd);
}
void _cvtsd2(int t, _OBJ_ *target, _OBJ_ *source){
char cmd[9];//结束符需要占1字节 \0
if(t == 1) strcpy( cmd, "cvtsd2ss"); //双转单
if(t == 2) strcpy( cmd, "cvtss2sd"); //单转双
// cvtsi2sd xmm, reg64 64位整数转双
// cvtsi2ss xmm, reg32 32位整数转单
// cvtsd2si reg64, xmm, 双转64位整数
// cvtss2si reg32, xmm, 单转32位整数
XmmSelect++;
fprintf(yyout, "%s%s %s, %s\n", Table, cmd , GetObj(target,EP_NULL), GetObj(source,EP_NOMemSize) );
}
void _fadd(DataType t, _OBJ_ *target){
char cmd[6]; //结束符需要占1字节 \0
if(t == DATA_TYPE_F_NUMBER_4) strcpy( cmd, "addss");
if(t == DATA_TYPE_F_NUMBER_8) strcpy( cmd, "addsd");
//内存取值
if(target){
fprintf(yyout, "%s%s xmm%lld, %s\n", Table, cmd, XmmSelect-1, GetObj(target,EP_NULL) );
}else{ //寄存器取值
XmmSelect--;
fprintf(yyout, "%s%s xmm%lld, xmm%lld\n", Table, cmd, XmmSelect-1, XmmSelect);
}
}
void _lea(_OBJ_ *target, _OBJ_ *source){
Command *cmd = (Command *)malloc(sizeof(Command));
cmd->op = AS_LEA;
cmd->target = target;
cmd->source = source;
ProduceAsm(cmd);
}
Assembly *GetCodeGenerator(){
Assembly *gen = (Assembly *)malloc(sizeof(Assembly));
gen->mov=_mov;
gen->lea=_lea;
gen->cvtsd2=_cvtsd2;
gen->fadd=_fadd;
gen->add=_add;
gen->sub=_sub;
gen->imul=_imul;
gen->idiv=_idiv;
gen->movsx=_movsx;
gen->push=_push;
gen->pop=_pop;
return gen;
}
Register SetReg(DataType t, Register base){
switch(t){
case DATA_TYPE_NUMBER_1: return base;
case DATA_TYPE_NUMBER_2: return (Register)(base+1);
case DATA_TYPE_NUMBER_4: return (Register)(base+2);
case DATA_TYPE_NUMBER_8: return (Register)(base+3);
case DATA_TYPE_STRING: return (Register)(base+3);
}
}
MemSize SetAsmSize(DataType t){
if(t==DATA_TYPE_NUMBER_1){
return MEM_BYTE;
}else if(t==DATA_TYPE_NUMBER_2){
return MEM_WORD;
}else if(t==DATA_TYPE_NUMBER_4||t==DATA_TYPE_F_NUMBER_4){
return MEM_DWORD;
}else if(t==DATA_TYPE_NUMBER_8||t==DATA_TYPE_F_NUMBER_8){
return MEM_QWORD;
}
}
_OBJ_ *imm(Num8 n){
_OBJ_ * obj = (_OBJ_ *)malloc(sizeof(_OBJ_));
obj->type = OBJ_IMM;
obj->Imm.n = n;
return obj;
}
_OBJ_ *mem(Num8 n, _OBJ_ *obj){
obj->type = OBJ_MEM;
obj->Imm.n = n;
return obj;
}
_OBJ_ *ax(DataType t){
_OBJ_ *obj = (_OBJ_ *)malloc(sizeof(_OBJ_));
obj->type = OBJ_REG;
obj->Reg.name = SetReg(t, R_AL);
obj->dt = t;
return obj;
}
_OBJ_ *bx(DataType t){
_OBJ_ *obj = (_OBJ_ *)malloc(sizeof(_OBJ_));
obj->type = OBJ_REG;
obj->Reg.name = SetReg(t, R_BL);
obj->dt = t;
return obj;
}
_OBJ_ *dx(DataType t){
_OBJ_ *obj = (_OBJ_ *)malloc(sizeof(_OBJ_));
obj->type = OBJ_REG;
obj->Reg.name = SetReg(t, R_DL);
obj->dt = t;
return obj;
}
_OBJ_ *xmm(){
_OBJ_ *obj = (_OBJ_ *)malloc(sizeof(_OBJ_));
obj->type = OBJ_REG;
obj->Imm.n = XmmSelect;
obj->Reg.name = R_XMM;
return obj;
}
_OBJ_ *memrel(Num4 no){
_OBJ_ *obj = (_OBJ_ *)malloc(sizeof(_OBJ_));
static char str[100];
sprintf(str, "[rel FLT%ld]", no);
obj->type = OBJ_STR;
obj->Str.name = str;
return obj;
}
_OBJ_ *bp(DataType t){
_OBJ_ *obj = (_OBJ_ *)malloc(sizeof(_OBJ_));
obj->type = OBJ_REG;
obj->Reg.size = SetAsmSize(t);
obj->Reg.name = R_RBP;
obj->dt = t;
return obj;
}
_OBJ_ *AutoReg(DataType t){
//程序逻辑
if(AutoRegSelect){
return bx(t);
}else{
AutoRegSelect = 1;
return ax(t);
}
}
_OBJ_ *Floating(DataType t){
_OBJ_ *obj = (_OBJ_ *)malloc(sizeof(_OBJ_));
obj->type = OBJ_STR;
obj->Str.size = SetAsmSize(t);
obj->Str.name = "FLT";
obj->dt = t;
return obj;
}
void PushParams(DataType t, Register s_r, Register t_r){
if( isReg8(s_r) || isReg16(s_r) ){
if(isNoSign(t))
fprintf(yyout, "%smovzx %s, %s\n", Table, GetRegName(t_r), GetRegName(s_r));
else
fprintf(yyout, "%smovsx %s, %s\n", Table, GetRegName(t_r), GetRegName(s_r));
}else if( isReg32(s_r) ){
fprintf(yyout, "%smov %s,%s\n", Table, GetRegName(t_r), GetRegName(s_r));
}else{
fprintf(yyout, "%smov %s,%s\n", Table, GetRegName((Register)(t_r+1)), GetRegName(s_r));
}
}
_OBJ_ *StackReg(Num no, DataType t){
//值在ax里面
Register _reg = SetReg(t, R_AL);
switch (no)
{
//di
case 1: PushParams(t, _reg, R_EDI); break;
//si
case 2: PushParams(t, _reg, R_ESI); break;
//dx
case 3: PushParams(t, _reg, R_EDX); break;
//cx
case 4: PushParams(t, _reg, R_ECX); break;
//r8
case 5: PushParams(t, _reg, R_R8D); break;
//r9
case 6: PushParams(t, _reg, R_R9D); break;
// push 64
default:
fprintf(yyout, "%spush rax\n", Table);
break;
}
}
_OBJ_ *StackXmm(Num no, DataType t){
//TODO
//如果是可变参数需要把float类型提升到double
//可以 cvtss2sd xmm0, xmm0
/*
movsx esi, BYTE [rbp-15]
movsx edx, WORD [rbp-14]
mov ecx, [rbp-12]
mov r8, [rbp-8]
lea rdi, [rel _str]
call out
*/
if(no<8){
if(no!=0) fprintf(yyout, "%smovapd xmm%d, xmm0\n", Table, no);
}else{// push mem
fprintf(yyout, "%smovq rax, xmm0\n", Table);
fprintf(yyout, "%spush rax\n", Table);
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。