d87-vik@dront.nada.kth.se (Ville K{rkk{inen) (10/20/90)
Organization: Royal Institute of Technology, Stockholm, Sweden I'm trying to access the Int 10 Function 13 ( Write string in teletype mode ) from Microsoft C 5.10. Everything has worked out fine so far, but today I found out that the calling convention requires the offset of the string to be stored in the BP register ! (BasePointer actually). Now I wonder, is there a way to set the BP from C, or do I have to write a .asm-hack that first saves the BP before the actual call, and then restores it.(Which if I'm not wrong requires an update to MSC 6.0) Any comments appreciated ! +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ----- We are confronted with vaste quantities of plastic people. F Zappa ------ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Ville.
trier@klah.INS.CWRU.Edu (Stephen C. Trier) (10/20/90)
In article <1990Oct19.202013.28397@nada.kth.se> d87-vik@dront.nada.kth.se (Ville K{rkk{inen) writes: >Now I wonder, is there a way to set the BP from C, or do I have to write a >.asm-hack that first saves the BP before the actual call, and then restores >it.(Which if I'm not wrong requires an update to MSC 6.0) Use the functions int86 or int86x. With these, you load your registers into a structure, then pass the registers to the function. The function takes care of the rest. All registers can be set this way. A C compiler that can't link to assembly is pretty poor. MS-C can certainly do it from version 4.0 on; I imagine it's been supported since version 1.0. -- Stephen Trier Case Western Reserve University Work: trier@cwlim.ins.cwru.edu Information Network Services Home: sct@seldon.clv.oh.us "If we can't fix it, it ain't broke." - Ernie Ellenberger
d87-vik@dront.nada.kth.se (Ville K{rkk{inen) (10/22/90)
Forgive me for not mentioning that I am aware of the existance of functions intdos,int86 and int86x. In fact I am using all of these, each when appropiate. So I just like to add this to my original posting before I drown in answers like "RTFM- use int86x.....!!!". The problem is *NOT* as easy as might be seen in a quick first glance. I have had no problems whatsoever using other functions that requires a pointer to some data to be stored as a segment and and an offset in that segment. My problem is that Int10h - Func13h requires the offset of my data to be stored in BP,that is, the BasePointer. Note this,BP is a pointer, not a register defined in the REGS union. Some of my answers has been quite helpful though, I have been told of the existance of a "regpacks" struct defined somewhere in TC (I'm stuck to MS-C 5.1), where the BP was accessible in "r_bp". So my problem is not a "what to do" one, but a "how to do". Any hints to where I can find a similar structure defined in MS-C appreciated. So please have patience with me and give it a little thought. Ville.
gday@digigw.digital.co.jp (Gordon Day) (10/23/90)
In article <1990Oct21.204236.22011@nada.kth.se>, d87-vik@dront.nada.kth.se (Ville K{rkk{inen) writes: > > My problem is that Int10h-Func13h requires the offset of my data to be stored > in BP,that is, the BasePointer. Note this,BP is a pointer, not a register > defined in the REGS union. Unfortunately, you can't do this from Microsoft C (at least, not without some inline assembler). The value of a specific register cannot be read or changed from C on the PC which is why the interrupt-type functions provided by the MSC libraries are implemented in assembly. The reason is that the definition of the language doesn't support the idea of "named" registers, that is, a mapping of a special variable name directly to a physical machine register. There is nothing stopping a compiler implementor from doing this (e.g. the VAX based BSD4.3 C compiler), but no compilers (to my knowledge) on the PC do, as it is both easier and much less of a bad hack to provide an assembly based library routine to do it. So, you'll have to grit your teeth and write a new "int86x()" that takes a REGS-type struct that includes a value to/from the BP register. It's not a terribly difficult thing to do, just remember not trash your stack frame. > So please have patience with me and give it a little thought. Consider it done. Gordon W. Day
nbladt@aut.UUCP (Norbert Bladt) (10/24/90)
trier@klah.INS.CWRU.Edu (Stephen C. Trier) writes: >In article <1990Oct19.202013.28397@nada.kth.se> d87-vik@dront.nada.kth.se (Ville K{rkk{inen) writes: >>Now I wonder, is there a way to set the BP from C, or do I have to write a [story about setting BP deleted] >>it.(Which if I'm not wrong requires an update to MSC 6.0) Right w.r.t. the update ! >Use the functions int86 or int86x. With these, you load your registers Right ! [more text how to use int86 deleted]. >A C compiler that can't link to assembly is pretty poor. MS-C can certainly >do it from version 4.0 on; I imagine it's been supported since version 1.0. You missed the point ! Inline assembly indeed requries MS-C 6.0 (and MASM or TASM I would guess). I once saw a program named MASM.EXE which just called TASM with some additional parameters, so you really don't need MASM. But, try it with the int86 or int86x, first. Norbert Bladt. -- Please use this path as return address. DON'T USE THE RETURN PATH IN THE HEADER Norbert Bladt, Ascom Autelca AG, Worbstr. 201, CH-3073 Guemligen, Switzerland Phone: +41 31 52 92 14 EMail: ..!uunet!mcsun!chx400!hslrswi!bladt
fmgst@unix.cis.pitt.edu (Filip Gieszczykiewicz) (10/24/90)
.>A C compiler that can't link to assembly is pretty poor. MS-C can certainly .>do it from version 4.0 on; I imagine it's been supported since version 1.0. .You missed the point ! .Inline assembly indeed requries MS-C 6.0 (and MASM or TASM I would guess). .I once saw a program named MASM.EXE which just called TASM with some additional .parameters, so you really don't need MASM. You can also use A86 assembler on Simtel. It has a .com file that you rename to MASM.COM and it executes like the real thing. I also think that it provides a more compact result and is _almost_ Masm comaptible. . .But, try it with the int86 or int86x, first. Weeeellll... First, it's slow. Second, you can't do anything other than they supply. For example, the guy is trying to use registers that are not passed by the INT86 routines (or so I understood) and it's foolish to rewrite them ;-) . .Norbert Bladt. Take care. -- _______________________________________________________________________________ "The Force will be with you, always." It _is_ with me and has been for 10 years Filip Gieszczykiewicz "... a Jedi does it with a mind trick... " ;-) FMGST@PITTVMS or fmgst@unix.cis.pitt.edu "My ideas. ALL MINE!!"
shurr@cbnews.att.com (Larry A. Shurr) (10/25/90)
In article <685@digigw.digital.co.jp>, gday@digigw.digital.co.jp (Gordon Day) writes: } In article <1990Oct21.204236.22011@nada.kth.se>, d87-vik@dront.nada.kth.se (Ville K{rkk{inen) writes: } } [Wishes to access BP from C source level in MSoft C.] } Unfortunately, you can't do this from Microsoft C (at least, not without some } inline assembler). } The reason is that the definition } of the language doesn't support the idea of "named" registers, that is, a } mapping of a special variable name directly to a physical machine register. } There is nothing stopping a compiler implementor from doing this (e.g. the } VAX based BSD4.3 C compiler), but no compilers (to my knowledge) on the PC do, You may be interested to know that Turbo C does provide this facility. Thus, one can write: _AX = 1; and the AX register gets the value 1. You must, however, keep your brain engaged when using this facility, I once coded the following: _AX = foo; _BX = this + that; Afterwords, both AX and BX contained the value of the expression "this + that." Imagine that! The compiler used the AX register to calculate the value of the expression, clobbering what I had put in there beforehand... just like you would expect. regards, Larry -- Larry A. Shurr (cbnmva!las@att.ATT.COM or att!cbnmva!las) The end of the world has been delayed due to a shortage of trumpet players. (The above reflects my opinions, not those of AGS or AT&T, but you knew that.)
Ralf.Brown@B.GP.CS.CMU.EDU (10/27/90)
In article <685@digigw.digital.co.jp>, gday@digigw.digital.co.jp (Gordon Day) wrote: }inline assembler). The value of a specific register cannot be read or changed }from C on the PC which is why the interrupt-type functions provided by the MSC }libraries are implemented in assembly. The reason is that the definition }of the language doesn't support the idea of "named" registers, that is, a }mapping of a special variable name directly to a physical machine register. }There is nothing stopping a compiler implementor from doing this (e.g. the }VAX based BSD4.3 C compiler), but no compilers (to my knowledge) on the PC do, Don't tell Turbo C, which has let you directly manipulate the CPU registers since v1.00. I regularly write code like _AX = 0x2B00 ; _CX = 0x4445 ; _DX = 0x5351 ; geninterrupt(0x21) ; if (_AL != 0xFF) DESQview_version = _BX ; else DESQview_version = 0 ; though it takes some care when putting things other than numeric literals into a register (since many complex assignments clobber other registers). TC will let you mess with BP, DS, SS, and SP, but one does so at one's own peril, since those registers are vital to the continued running of the compiled C code. -- UUCP: {ucbvax,harvard}!cs.cmu.edu!ralf -=- 412-268-3053 (school) -=- FAX: ask ARPA: ralf@cs.cmu.edu BIT: ralf%cs.cmu.edu@CMUCCVMA FIDO: 1:129/3.1 Disclaimer? | I was gratified to be able to answer promptly, and I did. What's that? | I said I didn't know. --Mark Twain
shack@cs.arizona.edu (David Shackelford) (10/30/90)
In article <685@digigw.digital.co.jp> gday@digigw.digital.co.jp (Gordon Day) writes: >In article <1990Oct21.204236.22011@nada.kth.se>, d87-vik@dront.nada.kth.se (Ville K{rkk{inen) writes: >> >> My problem is that Int10h-Func13h requires the offset of my data to be stored >> in BP,that is, the BasePointer. Note this,BP is a pointer, not a register >> defined in the REGS union. > [stuff on MSC & VAX deleted], but no compilers (to my knowledge) on the PC do, > >Gordon W. Day TurboC has aliases to the actual registers defined, and you can directly write to the hardware with a couple of restrictions. You cannot change the segment registers, SP, or BP. Unfortunately, this means that the original poster would not be able to use this anyway. I don't understand why the int86?() functions don't work, as the regs structure does contain a BP field, which is properly modified and sent to the BIOS func. (At least it is in TURBOC, can't say for other compilers). I use this all of the time in my mouse handler functions. Perhaps a code example from the non-working program might help to find a fix. Dave | shack@cs.arizona.edu
lsalomo@hubcap.clemson.edu (lsalomo) (10/30/90)
From article <488@caslon.cs.arizona.edu>, by shack@cs.arizona.edu (David Shackelford): > TurboC has aliases to the actual registers defined, and you can directly write > to the hardware with a couple of restrictions. You cannot change the segment > registers, SP, or BP. Unfortunately, this means that the original poster > would not be able to use this anyway. Yes, you can change any of the registers, provided you disable interrupts before the modification, and enable them afterwards. I wrote a multi-tasking OS kernal whose dispatcher did this very thing... Cheers, Q - the "Q"uestor for knowledge (, a degree, etc.) lsalomo@hubcap.clemson.edu ibmman@prism.clemson.edu ibmman@clemson.clemson.edu ============================================================================= "Gee Wally, I think there's something wrong with the Beaver." =============================================================================
hughes@locusts.Berkeley.EDU (Eric Hughes) (11/21/90)
In article <1990Oct21.204236.22011@nada.kth.se> d87-vik@dront.nada.kth.se (Ville K{rkk{inen) writes: >My problem is that Int10h - Func13h requires the offset of my data to >be stored in BP,that is, the BasePointer. Note this,BP is a pointer, >not a register defined in the REGS union. BP is the base pointer from which all auto variables are referenced and which saves the value of SP. If you change the value of BP, you must change it back again before the C function returns. The only code which changes BP in compiled code (for MS C 5.1, the compiler in question) are the function prolog and epilog, which set up the stack frame. Really, the easiest way to get at the BIOS service you want is to wrap it in some assembly language which uses the C calling convention. See the mixed model programming guide on how to do this. Now you *can*, through some total deviousness, get a copy of the string you want to print in the location pointed by BP and safely return from that function, but once you've done that, you need to invoke the interrupt without changing stack frames. I don't know of a way to trick MS C 5.1 into generating an int 10h instruction without using self-modifying code. (Take a pointer to a function which contains a dummy instruction, calculate an offset based on an assembly code listing, make sure you write into the code segment somehow, and poke in the instruction by hand.) The upshot of this is that assembly is pretty much required. Eric Hughes hughes@ocf.berkeley.edu
dgil@pa.reuter.COM (Dave Gillett) (11/30/90)
In <HUGHES.90Nov20114508@locusts.Berkeley.EDU> hughes@locusts.Berkeley.EDU (Eric Hughes) writes: >In article <1990Oct21.204236.22011@nada.kth.se> >d87-vik@dront.nada.kth.se (Ville K{rkk{inen) writes: >>My problem is that Int10h - Func13h requires the offset of my data to >>be stored in BP,that is, the BasePointer. Note this,BP is a pointer, >>not a register defined in the REGS union. >BP is the base pointer from which all auto variables are referenced >and which saves the value of SP. Function 13H actually has three problems: (a) It expects a pointer in ES:BP. BP is normally an offset into the Stack segment (SS:BP). So I expect that the function has internal overhead associated with making a usable address out of the supplied paramenters. (b) BP is unusable from high-level languages. As Eric has explained, BP is used to implement stack frames as part of the calling sequence generated by almost all MS-DOS compilers. So you effectively have to resort to assembly language (Turbo C's inline 'asm' keyword can help, but what if you're using some other compiler?) to use this function. (c) Many machine BIOSes don't have it. Maybe you don't consider this a problem, but *I* generally write stuff that should work on any PC. Now, since it is possible to write a routine which has all of the visible effects of function 13H, with none of these drawbacks and negligible performance difference, with only a trivial amount of effort, I would say that the correct answer to Ville is "Don't even try to use that function!" Dave Note: We don't get comp.os.msdos.* here, for some mysterious reason.