📄 disio.cpp
字号:
/************************************************************************
* disio.cpp *
* This is a fairly big class, and yet it was originally part of the *
* larger disasm class. I finally got around to splitting off some of *
* 3500 lines of code from that class into here. This represents the *
* disasm I/O functions for window I/O and file I/O. Version 2.11 was *
* when this was split. There are still a huge number of confusing *
* functions and code in here which probably needs more work to clean it *
* up, and better split/define the classes. Some of the functions are *
* friends of disasm because it has been difficult to split the classes *
* effectively and both access the complex main disassembly structures *
************************************************************************/
#include <windows.h>
#include <stdio.h> // for sprintf, for float printing
#include "disio.h"
#include "disasm.h"
#include "data.h"
#include "dasm.h"
#include "schedule.h"
#include "mainwind.h"
#include "gname.h"
#include "xref.h"
#include "range.h"
#include "debug.h"
/************************************************************************
* globals *
* - actually some constants used in file i/o as a header *
************************************************************************/
char hdr[] ="; Created by Borg Disassembler\r\n";
char hdr2[]="; written by Cronos\r\n";
/************************************************************************
* constructor function *
* - this just enables window updates and sets the subline to null *
* - the subline (subitem) is basically the line in the disassembly that *
* you see for any given loc. As a loc may refer to many lines (like *
* segheader, comments, xref, actual instruction are all separate *
* line, and subline says which of these it is) *
************************************************************************/
disio::disio()
{ subitem=dsmnull;
}
/************************************************************************
* destructor function *
* - currently null *
* - note that disio has no particular structs the same way most of the *
* other classes in Borg do *
************************************************************************/
disio::~disio()
{
}
/************************************************************************
* argoverdec *
* - disio also acts as a go between for the user and the disasm engine *
* - here we translate the users current line of the disassembly and *
* their request for a decimal override into a call to the disasm *
* engine to add the override to the instruction that is there *
* - note that these kind of calls come from the scheduler and are part *
* of the secondary thread *
************************************************************************/
void disio::argoverdec(void)
{ lptr outhere;
findcurrentaddr(&outhere);
dsm.disargoverdec(outhere);
}
/************************************************************************
* argoversingle *
* - very similar to argoverdec, for a single (float) override *
************************************************************************/
void disio::argoversingle(void)
{ lptr outhere;
findcurrentaddr(&outhere);
dsm.disargoversingle(outhere);
}
/************************************************************************
* argovernegate *
* - very similar to argoverdec, for an argument negation override *
************************************************************************/
void disio::arg_negate(void)
{ lptr outhere;
findcurrentaddr(&outhere);
dsm.disargnegate(outhere);
}
/************************************************************************
* argoverhex *
* - very similar to argoverdec, for a hex override *
************************************************************************/
void disio::argoverhex(void)
{ lptr outhere;
findcurrentaddr(&outhere);
dsm.disargoverhex(outhere);
}
/************************************************************************
* argoveroffsetdseg *
* - very similar to argoverdec, for a dseg override *
************************************************************************/
void disio::argoveroffsetdseg(void)
{ lptr outhere;
findcurrentaddr(&outhere);
dsm.disargoveroffsetdseg(outhere);
}
/************************************************************************
* argoverchar *
* - very similar to argoverdec, for a char override *
************************************************************************/
void disio::argoverchar(void)
{ lptr outhere;
findcurrentaddr(&outhere);
dsm.disargoverchar(outhere);
}
/************************************************************************
* makedword *
* - disio acts as a go between for the user and the disasm engine *
* - here we translate the users current line of the disassembly and *
* their request for a dword into a call to the disasm engine to *
* disassemble a dword at the current point *
* - note that these kind of calls come from the scheduler and are part *
* of the secondary thread *
************************************************************************/
void disio::makedword(void)
{ lptr outhere;
findcurrentaddr(&outhere);
if(outhere==curraddr)
subitem=dsmnull;
dsm.disdatadword(outhere);
}
/************************************************************************
* makesingle *
* - very similar to makedword, this time to disassemble a single *
* (float) *
************************************************************************/
void disio::makesingle(void)
{ lptr outhere;
findcurrentaddr(&outhere);
if(outhere==curraddr)
subitem=dsmnull;
dsm.disdatasingle(outhere);
}
/************************************************************************
* makedouble *
* - very similar to makedword, this time to disassemble a double *
* (double float) *
************************************************************************/
void disio::makedouble(void)
{ lptr outhere;
findcurrentaddr(&outhere);
if(outhere==curraddr)
subitem=dsmnull;
dsm.disdatadouble(outhere);
}
/************************************************************************
* makelongdouble *
* - very similar to makedword, this time to disassemble a long double *
* (long double) *
************************************************************************/
void disio::makelongdouble(void)
{ lptr outhere;
findcurrentaddr(&outhere);
if(outhere==curraddr)
subitem=dsmnull;
dsm.disdatalongdouble(outhere);
}
/************************************************************************
* makeword *
* - very similar to makedword, this time to disassemble a word *
************************************************************************/
void disio::makeword(void)
{ lptr outhere;
findcurrentaddr(&outhere);
if(outhere==curraddr)
subitem=dsmnull;
dsm.disdataword(outhere);
}
/************************************************************************
* makestring *
* - very similar to makedword, this time to disassemble a string *
* (standard C string) *
************************************************************************/
void disio::makestring(void)
{ lptr outhere;
findcurrentaddr(&outhere);
if(outhere==curraddr)
subitem=dsmnull;
dsm.disdatastring(outhere);
}
/************************************************************************
* pascalstring *
* - very similar to makedword, this time to disassemble a string *
* (standard pascal string) *
************************************************************************/
void disio::pascalstring(void)
{ lptr outhere;
findcurrentaddr(&outhere);
if(outhere==curraddr)
subitem=dsmnull;
dsm.disdatapstring(outhere);
}
/************************************************************************
* ucstring *
* - very similar to makedword, this time to disassemble a string *
* (unicode C string) *
************************************************************************/
void disio::ucstring(void)
{ lptr outhere;
findcurrentaddr(&outhere);
if(outhere==curraddr)
subitem=dsmnull;
dsm.disdataucstring(outhere);
}
/************************************************************************
* upstring *
* - very similar to makedword, this time to disassemble a string *
* (unicode pascal string) *
************************************************************************/
void disio::upstring(void)
{ lptr outhere;
findcurrentaddr(&outhere);
if(outhere==curraddr)
subitem=dsmnull;
dsm.disdataupstring(outhere);
}
/************************************************************************
* dosstring *
* - very similar to makedword, this time to disassemble a string *
* (dos style string) *
************************************************************************/
void disio::dosstring(void)
{ lptr outhere;
findcurrentaddr(&outhere);
if(outhere==curraddr)
subitem=dsmnull;
dsm.disdatadosstring(outhere);
}
/************************************************************************
* generalstring *
* - very similar to makedword, this time to disassemble a string *
* (general string) *
************************************************************************/
void disio::generalstring(void)
{ lptr outhere;
findcurrentaddr(&outhere);
if(outhere==curraddr)
subitem=dsmnull;
dsm.disdatageneralstring(outhere);
}
/************************************************************************
* makecode *
* - very similar to makedword, but this time to disassemble as code *
* from the current location, and continue disassembling *
************************************************************************/
void disio::makecode(void)
{ lptr outhere;
findcurrentaddr(&outhere);
if(outhere==curraddr)
subitem=dsmnull;
dsm.disblock(outhere);
}
/************************************************************************
* vertsetpos *
* - this function takes a position of the vertical scroll bar, from 0 *
* to the VERTSCROLLRANGE and it sets the current address to that *
* point *
************************************************************************/
void disio::vertsetpos(int pos)
{ float sbarpos;
sbarpos=((float)pos)/((float)VERTSCROLLRANGE)*(float)total_data_size;
setcuraddr(dta.getlocpos((unsigned long)sbarpos));
}
/************************************************************************
* setcuraddr *
* - sets the address as a location for the screen output to start at *
* - also sets the scroll bar position for the vertical scroll bar *
* - also ensures that its not set to a mid-instruction address and *
* sets the subline *
* - called from many places in the source code *
************************************************************************/
void disio::setcuraddr(lptr loc)
{ dsmitem titem,*tblock;
float sbarpos;
dsegitem *l_ds;
// check for non-existant address added v2.20
l_ds=dta.findseg(loc);
if(l_ds==NULL)
return;
curraddr=loc;
titem.addr=curraddr;
titem.type=dsmnull;
dsm.findnext(&titem);
tblock=dsm.nextiterator();
if(tblock!=NULL)
subitem=tblock->type;
else
subitem=dsmnull;
tblock=dsm.nextiter_code(tblock);
if(tblock!=NULL)
{ if(loc.between(tblock->addr,tblock->addr+tblock->length-1))
curraddr=tblock->addr;
}
outend=loc+50;
usersel=0;
userselonscreen=true;
updatewindow();
current_data_pos=dta.datagetpos(loc);
sbarpos=((float)current_data_pos)/((float)total_data_size+(float)1.0)*(float)VERTSCROLLRANGE;
SetScrollPos(mainwindow,SB_VERT,(int)sbarpos,true);
}
/************************************************************************
* setpos *
* - when the left mouse button is pressed the line is changed to the *
* line the mouse points at. This routine sets the line, and asks for *
* a screen update if needed (the screen update method here is a *
* primary thread request that simply invalidates the window rather *
* than requesting through the scheduler...... but this is very very *
* old code.... *
************************************************************************/
void disio::setpos(int ypos)
{ if(usersel!=ypos/cyc)
{ usersel=ypos/cyc;
InvalidateRect(mainwindow,NULL,true);
}
}
/************************************************************************
* printlineheader *
* - prints an appropriate line header with the address if needed and *
* sets the cursor position for the next LastPrintBuff call *
************************************************************************/
void disio::printlineheader(lptr loc,bool printaddrs)
{ if(options.mode32)
{ if(printaddrs)
PrintBuff("%04lx:%08lx",loc.segm,loc.offs);
else
PrintBuff("");
LastPrintBuffEpos(BYTEPOS);
}
else
{ if(printaddrs)
PrintBuff("%04lx:%04lx",loc.segm,loc.offs);
else
PrintBuff("");
LastPrintBuffEpos(BYTEPOS-4);
}
}
/************************************************************************
* outinst *
* - this is the routine which results in the output of an address, hex *
* bytes, instruction and arguments *
************************************************************************/
void disio::outinst(dsmitem *inst,bool printaddrs)
{ dsegitem *dblock;
int i;
int prefixptr;
byte pbyte;
printlineheader(inst->addr,printaddrs);
dblock=dta.findseg(inst->addr); // find segment item.
switch(inst->type)
{ case dsmcode:
i=inst->length;
if(printaddrs)
{ while(i)
{ if(dblock!=NULL)
{ if(dblock->typ==uninitdata)
LastPrintBuff("??");
else
LastPrintBuff("%02x",inst->data[inst->length-i]);
}
else
LastPrintBuff("%02x",inst->data[inst->length-i]);
i--;
if(((i+8)<inst->length)&&(inst->length>10))
{ LastPrintBuff("..");
break;
}
}
}
if(options.mode32)
LastPrintBuffEpos(ASMPOS+4);
else
LastPrintBuffEpos(ASMPOS);
if(inst->flags&FLAGS_PREFIX)
{ prefixptr=0;
while(!isprefix(inst->data[prefixptr])&&(prefixptr<15))
prefixptr++;
pbyte=inst->data[prefixptr];
outprefix(pbyte);
}
LastPrintBuff(DSMITEM_NAME(inst));
LastPrintBuff(" ");
if(options.mode32)
LastPrintBuffEpos(ARGPOS+4);
else
LastPrintBuffEpos(ARGPOS);
if(dblock!=NULL)
{ if(dblock->typ==uninitdata)
LastPrintBuff("?");
else
{ outargs(inst,DSMITEM_ARG1(inst));
if(DSMITEM_ARG2(inst)!=ARG_NONE)
{ LastPrintBuff(", ");
outargs(inst,DSMITEM_ARG2(inst));
}
if(DSMITEM_ARG3(inst)!=ARG_NONE)
{ LastPrintBuff(", ");
outargs(inst,DSMITEM_ARG3(inst));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -