📄 outasm.c
字号:
#include <stdio.h>
#include "utility.h"
#include "genasm.h"
//the same order as enum en_opcode
char *optab[]={
"mov", "movsx","movzx","push", "pop", "lea", "xchg",
"add", "sub", "inc", "dec", "neg", "cmp",
"jmp", "jz", "jnz",
"jg", "jge", "jl", "jle",
"ja", "jae", "jb", "jbe",
"imul", "idiv", "mul", "div", "cdq", //sign extension
"and", "or", "xor", "not", "test", //bit calc
"sal", "shl", "sar", "shr", "call", "",
"cld", "rep", "movsb"
};
void put_pointer(int size)
{
switch (size) {
case 10:
printf("tword ");
break;
case 8:
printf("qword ");
break;
case 6:
printf("fword ");
break;
case 4:
printf("dword ");
break;
case 2:
printf("word ");
break;
case 1:
printf("byte ");
break;
default:
debug("Bad pointer");
}
printf("ptr ");
return ;
}
void put_opcode(int opcode)
{
printf("%-12s", optab[opcode]);
return ;
}
//remember register no from 1 to 8
void put_reg(int reg, int size)
{
static char *regname[4][8]={
{ "al","cl","dl","bl","ah","ch","dh","bh" },
{ "ax", "cx", "dx","bx","si","di","sp","bp" },
{0},
{ "eax", "ecx", "edx","ebx","esi","edi","esp","ebp" }};
printf(regname[--size][reg]);
return ;
}
void put_addrmode(AddrMode *am)
{
switch(am->mode)
{
case am_label:
if(am->entry)
printf("%s ", am->entry);
else
printf("_lb_%ld ", am->offset);
break;
case am_imme:
if(am->entry)//const pointer offset
{
printf("offset %s ", am->entry);
if(am->offset>0)
printf(" + 0%lxh", am->offset);
else if(am->offset<0)
printf(" - 0%lxh", -am->offset);
}
else
{
printf("0%lxh ", am->offset);
}
break;
case am_dreg:
put_reg(am->base_reg, am->size);
break;
case am_freg:
printf("ST(%d)", am->base_reg);
break;
case am_direct:
put_pointer(am->size);
if(am->entry)//const pointer offset
{
printf("[ %s ", am->entry);
if(am->offset>0)
printf(" + 0%lxh", am->offset);
else if(am->offset<0)
printf(" - 0%lxh", -am->offset);
putchar(']');
}
break;
case am_relative:
put_pointer(am->size);
putchar('[');
put_reg(am->base_reg, 4);
if(am->offset>0)
printf(" + 0%lxh", am->offset);
else if(am->offset<0)
printf(" - 0%lxh", -am->offset);
putchar(']');
break;
case am_scale:
put_pointer(am->size);
putchar('[');
put_reg(am->base_reg, 4);
if(am->index_reg!=UNKNOWN)
{
if(am->scale>1)
printf(" + 0%x*", am->scale);
else
printf(" + ", am->scale);
put_reg(am->index_reg, 4);
}
if(am->offset>0)
printf(" + 0%lxh", am->offset);
else if(am->offset<0)
printf(" - 0%lxh", -am->offset);//???????need check
putchar(']');
break;
default:
debug("Unknown address mode");
}
return ;
}
/*
The main routine of generate asm code
output a instruct
*/
void put_outcode(OutCode *oc)
{
if(oc->opcode == op_label)
{
printf("_lb_%ld:\n", (long)oc->opd1);
return;
}
if(oc->opcode == op_rep)
{
printf("\trep");
return;
}
putchar('\t');
put_opcode(oc->opcode);
if(oc->opcode == op_call && oc->opd1->mode==am_imme)
{
puts(oc->opd1->entry);//an ugly patch...
return ;
}
if(oc->opd1)
{
put_addrmode(oc->opd1);
if(oc->opd2)
{
printf(", ");
put_addrmode(oc->opd2);
}
}
putchar('\n');
return ;
}
/*
Output the header content of the asm file
*/
void asm_header(void)
{
printf("\
.386p\n\
.model flat\n\n\n\
.code\n");
return;
}
void asm_func_begin(
char *func_name,
long localdata
)
{
printf("\
%-10s proc\n\
push ebp\n\
mov ebp, esp\n", func_name);
if(localdata>0)printf("\
sub esp, 0%lxh\n", localdata);
printf("\
push ebx\n\
push esi\n\
push edi\n");
return ;
}
void asm_func_end(
char *func_name
)
{
printf("\
pop edi\n\
pop esi\n\
pop ebx\n\
mov esp, ebp\n\
pop ebp\n\
ret\n\
%-10s endp\n", func_name);
return ;
}
/*
Output the global variables and const string,
including data segment and bss segment
*/
void asm_globaldata(void)
{
char *str, ch;
Symbol *sym;
printf("\
.const\n\
string label byte\n");
while(str = popfront_List(&const_list))
{
int in=false;
printf("\tdb\t");
while(ch=*str++)
{
if(ch<32)
{
if(in)
{
printf("\",0%xh,", ch);
in=false;
}
else
printf("0%xh,", ch);
}
else
{
if(!in)
{
in=true;
printf("\"%c",ch);
}
else
putchar(ch);
}
}
if(in)printf("\",00h\n");
else printf("00h\n");
}
printf("\
.data\n");
while(sym= popfront_List(&data_list))
{
long i=1, size = sym->datatype->size;
char *data=sym->init;
printf("%-6s db 0%lxh 0%xh",
sym->value.linkname, size, *data);
for(;i<size;i++)
printf(",0%xh", data[i]);
putchar('\n');
}
printf("\
.data?\n");
while(sym= popfront_List(&bss_list))
{
if(sym->datatype->size>1)printf("%-6s db 0%lxh dup(?)\n",
sym->value.linkname, sym->datatype->size);
else printf("%-6s db ?\n",
sym->value.linkname, sym->datatype->size);
}
return ;
}
/*
* Output the fixup tables and the global/external list
*/
void asm_externdecl(void)
{
Symbol *sym;
while(sym= popfront_List(&extern_list))
{
if(sym->storage_class == sc_external)
{
if(sym->refcount<=0)
continue;
if(sym->datatype->basic_type == bt_funcptr
&&sym->const_flag)
{
printf("extrn %s:proc\n", sym->name);
}
else
printf("extrn %s:byte\n", sym->value.linkname);
}
else if(sym->storage_class == sc_global)
printf("public %s\n", sym->name);
}
printf("end\n");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -