📄 disio.cpp
字号:
{ outhere.assign(tblock->addr.segm,((word *)(&data[1]))[0]);
}
break;
case 3:
break;
}
if(dta.findseg(outhere)!=NULL)
{ retstack.push(curraddr);
setcuraddr(outhere);
updatewindow();
}
break;
default:
break;
}
}
}
}
/************************************************************************
* findcurrentline *
* - this routine finds the current screen address and output line in *
* the disassembly database and from there works out the disassembly *
* item on the currently selected line. *
* - it is used by jumpto, when the user presses return to follow a jump *
* - comments added to the procedure, it is a useful one to follow and *
* see the strategy employed, which is a fairly common Borg strategy *
************************************************************************/
dsmitem *disio::findcurrentline(void)
{ dsmitem titem,*tblock;
lptr outhere;
unsigned int i;
// strategy
// - use pointer to first item if available (so comments,etc included in list
// - otherwise use address.
titem.addr=curraddr;
titem.type=subitem;
// hunt for current addr and subitem
tblock=dsm.find(&titem);
if(tblock!=NULL)
tblock=dsm.nextiterator();
// on overlap - reset the curraddr.
// [on the spot error correction]
if(tblock!=NULL)
{ if(curraddr.between(tblock->addr,tblock->addr+tblock->length-1))
curraddr.offs=tblock->addr.offs;
}
// ensure we point to the right item, or the next one
if(tblock!=NULL)
{ if((tblock->addr<curraddr)||((tblock->addr==curraddr)&&(tblock->type<subitem)))
tblock=dsm.nextiterator();
}
// now at the top of the screen, the next loop moves down to the user selection line
outhere=curraddr;
for(i=0;i<usersel;i++)
{ if(tblock!=NULL)
{ if(outhere==tblock->addr)
{ outhere+=tblock->length;
tblock=dsm.nextiterator();
}
else
outhere++;
}
else
outhere++;
// check if gone beyond seg, get next seg.
if(dta.beyondseg(outhere))
{ outhere.offs--;
dta.nextseg(&outhere);
}
if(!outhere.segm)
break;
}
// now we either have the line we are pointing to, in the database
// or we have moved beyond the database and have a null
// or we have an address which would be a db
if(tblock!=NULL)
if(outhere!=tblock->addr)
return NULL;
return tblock;
}
/************************************************************************
* findcurrentaddr *
* - this is very similar to findcurrentline, but it instead finds just *
* the location. the search strategy is the same *
************************************************************************/
void disio::findcurrentaddr(lptr *loc)
{ dsmitem titem,*tblock;
lptr outhere;
unsigned int i;
// strategy
// - use pointer to first item if available (so comments,etc included in list
// - otherwise use address.
titem.addr=curraddr;
titem.type=subitem;
tblock=dsm.find(&titem);
if(tblock!=NULL)
tblock=dsm.nextiterator();
if(tblock!=NULL)
{ if(curraddr.between(tblock->addr,tblock->addr+tblock->length-1))
curraddr.offs=tblock->addr.offs;
}
if(tblock!=NULL)
{ if(tblock->addr<curraddr)
tblock=dsm.nextiterator();
}
// added 2.25 - bugfix
// - wasnt finding correct lines when in mid-line......
if(tblock!=NULL)
{ while((tblock->addr==curraddr)&&(tblock->type<subitem))
{ tblock=dsm.nextiterator();
if(tblock==NULL)
break;
}
}
outhere=curraddr;
for(i=0;i<usersel;i++)
{ if(tblock!=NULL)
{ if(outhere==tblock->addr)
{ outhere+=tblock->length;
tblock=dsm.nextiterator();
}
else
outhere++;
}
else
outhere++;
// check if gone beyond seg, get next seg.
if(dta.beyondseg(outhere))
{ outhere.offs--;
dta.nextseg(&outhere);
}
if(!outhere.segm)
break;
}
if(outhere.segm)
(*loc)=outhere;
else
(*loc)=curraddr;
}
/************************************************************************
* savecuraddr *
* - this simply saves the window top line location to the return stack *
* - this is called when the user selects to jump somewhere (like to a *
* named location) rather than the 'jumpto' routine used to jump to a *
* location specified by a disassembly argument *
************************************************************************/
void disio::savecuraddr(void)
{ retstack.push(curraddr);
}
/************************************************************************
* updatewindowifwithinrange *
* - adds a scheduler task for a window update if the current window *
* overlaps with the specified range *
************************************************************************/
void disio::updatewindowifwithinrange(lptr loc_start,lptr loc_end)
{ if((loc_end>=curraddr)&&(loc_start<=outend))
scheduler.addtask(windowupdate,priority_window,nlptr,NULL);
}
/************************************************************************
* updatewindowifinrange *
* - adds a scheduler task for a window update if the current window *
* contains the loc specified *
************************************************************************/
void disio::updatewindowifinrange(lptr loc)
{ if(loc.between(curraddr,outend))
scheduler.addtask(windowupdate,priority_window,nlptr,NULL);
}
/************************************************************************
* updatewindow *
* - this function rewrites the buffers for the disassembly output to *
* the window, and then requests a screen refresh which will paint the *
* buffers into the window. The ClearBuff and DoneBuff functions *
* when the buffers are full and it is safe to refresh the screen with *
* a repaint *
************************************************************************/
// this functions job to output a window
// of disassembly to the buffer.
void disio::updatewindow(void)
{ dsmitem titem,*tblock;
lptr outhere;
int i;
// find current position.
titem.addr=curraddr;
titem.type=subitem;
tblock=dsm.find(&titem);
if(tblock!=NULL)
tblock=dsm.nextiterator();
// now tblock= current position, or previous one.
// check if in middle of instruction
if(tblock!=NULL)
{ // bugfix 2.27
if(tblock->length>1)
if(curraddr.between(tblock->addr,tblock->addr+tblock->length-1))
{ curraddr.offs=tblock->addr.offs;
subitem=tblock->type;
}
}
// check if previous one. get next
if(tblock!=NULL)
{ if((tblock->addr<curraddr)||
((tblock->addr==curraddr)&&(tblock->type<subitem)))
tblock=dsm.nextiterator();
}
// tblock is now top of the page.
outhere=curraddr;
ClearBuff(); // start again
for(i=0;i<buffer_lines;i++)
{ if(tblock!=NULL)
{ if(outhere==tblock->addr)
{ switch(tblock->type)
{ case dsmcode:
outinst(tblock,true);
break;
case dsmnameloc:
printlineheader(tblock->addr,true);
LastPrintBuff("%s:",tblock->data);
break;
case dsmxref:
printlineheader(tblock->addr,true);
LastPrintBuff(";");
LastPrintBuffEpos(COMMENTPOS);
LastPrintBuff("XREFS First: ");
xrefs.printfirst(tblock->addr);
break;
default:
printlineheader(tblock->addr,true);
outcomment(tblock);
break;
}
outhere+=tblock->length;
tblock=dsm.nextiterator();
}
else
{ outdb(&outhere,true);
outhere++;
}
}
else
{ outdb(&outhere,true);
outhere++;
}
// check if gone beyond seg, get next seg.
if(dta.beyondseg(outhere))
{ outhere.offs--;
dta.nextseg(&outhere);
}
if(!outhere.segm)
break;
else
outend=outhere;
}
DoneBuff(); // mark as done
InvalidateRect(mainwindow,NULL,true);
}
/************************************************************************
* scroller *
* - this routine controls simple vertical scrolls. A vertical scroll is *
* a movement of the currently selected line. Only if this line moves *
* beyond the boundaries of the window do we need to move the windowed *
* disassembly output itself. Simple moves are handled quickly, and if *
* we need to regenerate the buffers then we first recalculate the top *
* position and then we call windowupdate to handle the rest. *
************************************************************************/
void disio::scroller(dword amount)
{ dsmitem titem,*tblock;
RECT r;
float sbarpos;
// simple move on screen
if((amount==1)&&(usersel<=nScreenRows-3))
{ usersel++;
r.left=0;
r.right=rrr;
r.top=(usersel-1)*cyc;
r.bottom=(usersel+1)*cyc;
InvalidateRect(mainwindow,&r,true);
return;
}
// simple move on screen
if((amount==(dword)(-1))&&(usersel))
{ usersel--;
r.left=0;
r.right=rrr;
r.top=usersel*cyc;
r.bottom=(usersel+2)*cyc;
InvalidateRect(mainwindow,&r,true);
return;
}
// find top of page
titem.addr=curraddr;
titem.type=subitem;
tblock=dsm.find(&titem);
// tblock is now top of page or previous item.
// if moving up find previous inst
if(amount<100)
if(tblock!=NULL)
tblock=dsm.nextiterator();
if(amount>100)
if(tblock!=NULL)
if((tblock->addr==titem.addr)&&(tblock->type==subitem))
tblock=dsm.lastiterator();
// move up - tblock=previous inst.
// if moving down, check if tblock=previous item.
if((tblock!=NULL)&&(amount<100))
{ if((tblock->addr<curraddr)||
((tblock->addr==curraddr)&&(tblock->type<subitem)))
tblock=dsm.nextiterator();
}
// moving down - tblock=current top.
if(amount<100)
while(amount)
{ if(usersel<=nScreenRows-3)
usersel++;
else
{ if(tblock!=NULL)
{ if(curraddr==tblock->addr)
{ curraddr+=tblock->length;
tblock=dsm.nextiterator();
if(tblock!=NULL)
{ if(curraddr==tblock->addr)
subitem=tblock->type;
else
subitem=dsmcode;
}
else
subitem=dsmcode;
}
else
{ subitem=dsmnull;
curraddr++;
}
}
else
{ subitem=dsmnull;
curraddr++;
}
// check if gone beyond seg, get next seg.
if(dta.beyondseg(curraddr))
{ curraddr.offs--;
dta.nextseg(&curraddr);
subitem=dsmnull;
}
if(!curraddr.segm)
break;
titem.addr=curraddr;
}
amount--;
}
else
{ while(amount)
{ if(usersel)
usersel--;
else
{ if(tblock!=NULL)
{ if(curraddr==tblock->addr+tblock->length)
{ curraddr.offs-=tblock->length;
subitem=tblock->type;
tblock=dsm.lastiterator();
}
else
{ subitem=dsmcode;
curraddr.offs--;
}
}
else
{ subitem=dsmnull;
curraddr.offs--;
}
// check if gone beyond seg, get previous seg.
if(dta.beyondseg(curraddr))
{ curraddr++;
dta.lastseg(&curraddr);
}
if(!curraddr.segm)
break;
titem.addr=curraddr;
}
amount++;
}
}
if(!curraddr.segm)
curraddr=titem.addr;
updatewindow();
current_data_pos=dta.datagetpos(curraddr);
sbarpos=((float)current_data_pos)/((float)total_data_size+(float)1.0)*(float)VERTSCROLLRANGE;
SetScrollPos(mainwindow,SB_VERT,(int)sbarpos,true);
}
/************************************************************************
* outargs *
* - this is a very long routine which handles every kind of argument *
* that we have set up in the processor tables. It outputs the ascii *
* form of the instructions arguments to the buffer. It handles *
* complex modrm and sib encodings, the display of names and locations *
* which must be decoded, etc. *
************************************************************************/
void disio::outargs(dsmitem *inst,argtype a)
{ byte *dta,modrm,sib;
// rm extended to word. build 15. re M Ogden and VC++ warnings.
word rm;
argtype a1,a2;
dword targetd;
dword targetw;
lptr loc;
char fbuff[40];
int i,sp; // sp= string printed
byte pbyte; // prefix byte.
int prefixptr;
if(inst->flags&FLAGS_SEGPREFIX)
{ prefixptr=0;
while(!issegprefix(inst->data[prefixptr])&&(prefixptr<15))
prefixptr++;
pbyte=inst->data[prefixptr];
}
if(inst->flags&FLAGS_ADDRPREFIX)
options.mode32=!options.mode32;
switch(a)
{ case ARG_REG_AX:
if(inst->mode32)
LastPrintBuff("eax");
else
LastPrintBuff("ax");
break;
case ARG_REG_BX:
if(inst->mode32)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -