mbeck@wheaties.ai.mit.edu (Mark Becker) (03/01/90)
Hello * [ This is a repost.. drive holding news filled up and wouldn't permit posts to escape. ] Some time ago I asked for suggestions on assembling a JMP FAR 0:0 using Borland's TASM 1.5 and TLINK 1.01 . Here is a summary of the responses. Several suggested I use DB statements and explicitly declare the opcodes in hex to defeat the assembler. This works.. but also as suggested, isn't really readable or easy to maintain. It does do the job though. qmsseq!pipkins offered some comments on how self-modifying code was bad and a really relevent comment on how this could mess up a program given that the Intel 80x8{8|6} processors have instruction prefetch queues. Changing the effective address of an instruction during a prefetch isn't exactly a good technique. Definitely a good way to wind up in Deep Space. Also, if using an 80286 or 80386 in protected mode, my code would generate an illegal exeception and abort. (TSR's probably wouldn't be found in such an environment.. but it's a good idea to be aware of the limitation!) Now I know why Borland high level languages generate (and why several respondents suggested): function DWORD db 4*(?) . . . leap: jmp dword far cs:[label] That is the code generated by TCC 2.01. in response to C code: void far (*function)(void); main() { (*function)(); } qmsseq!pipkins suggested an alternative: Push ES Push BX RetF I'll have to think about that.. it requires the proper data in ES:BX and thats only established at initialization time, not during normal execution. howardm@Neon.Standford.EDU had a fix for the label I used that seemed to stimulate TASM into generating the kind of code I wanted. d SEGMENT at 0h lab dw ? d ENDS . . . ; JMP far lab ;jmp lab DB 0EAh DW OFFSET LAB DW SEG d This got me thinking about what I had and I tried: j segment at 0 ; segment:offset of j is now.. org 0 ; .. known at compile time. farjump label far j ends ; ; Down in the code area.. jmp farjump TLINK gave no complaints about forming a COM file when resolving a .OBJ into a .COM using this construct. One wrote: You are writing for Intel segmented architecture, therefore you are living in a silly world. Ouch. :-) Well, yeah.. I like 'flat' architectures too. But sometimes taking on a challenge is good for the soul. And definitely generates dark spots under one's eyes. :-) (No flames.. they'll be cheerfully dumped to /dev/null :-) ). This same respondent added: Probably incorrect segment definition of 'farptr'. And my adding "AT 0" to the segment definition around farptr seems to have fixed that. ---------------------------------------- With regards to the request for a 16-bit in-segment jump, I'm still having problems. Several people suggested code of the form: jmp Next Next: . . . Yes, the jump references a label that hasn't yet been seen. But TASM still generates a short jump and adds in a NOP byte... I guess TASM is establishing the address of the label by assuming it's a 16-bit offset but then inserting code for a SHORT (1-byte) jump and filling the unused byte with the NOP. By a 16-bit in-segment jump, I meant a jump that would load IP directly from memory and not depend on an offset calculation within the processor. Actually I found this construct in my BIOS and didn't understand why until one late respondent pointed out that early some versions of IC's in PC's had problems with back-to-back I/O-space references. I would like to thank those that responded: Brad Jones <bjones@uhccux.uhcc.hawaii.edu> Eric Ng <c162-dr@zooey.berkeley.edu> Noel <santa@bourbaki.mit.edu> Otto J. Makela <otto@jyu.fi> Jeff Pipkins <qmsseq!pipkins@decwrl.dec.com> Lepp{j{rvi Jouni <so-jml@stekt.oulu.fi> Frank Whaley <few@quad1.quad.com> Howard A. Miller <howardm@Neon.Stanford.EDU> Ralf Brown <Ralf.Brown@b.gp.cs.cmu.edu> -- +-----------------------------------------------+-----------------------+ | Mark Becker | .signature under | | Internet: mbeck@ai.mit.edu | construction | +-----------------------------------------------+-----------------------+