PDA

View Full Version : another C noob question (accessing registers)



Mike Chambers
August 18th, 2010, 12:03 AM
does anybody who has some experience with MS QuickC know of the easiest way to access (read+modify) the general and segment registers in it? it's nice and hassle-free in Borland Turbo C, just having to use _AX, _BX, etc as if they were any other variable.

something like that would be great, or do i always have to "_asm mov" them into another var?

Chuck(G)
August 18th, 2010, 12:18 AM
Generally, inline assembly is the way to do this, but it depends on what you're trying to do. For example, using register in _int86 and _int86x is a matter of accessing a struct. But then, you already knew that.

What are you trying to do?

Mike Chambers
August 18th, 2010, 07:29 AM
what i'm trying to do is hook int 13h (this much is already done), and then the first thing i want to do is look at the value of DL and depending on that either chain to the original routine or bypass it and handle the call myself. i'll also need to be able to pass modified registers back to the calling function. this is going to be a virtual floppy drive that lets you work with disk images in DOS like a real disk. the point behind this is to get practice writing TSRs.

so, basically:


void _interrupt _far newhandler() {
//HERE is where i need to take a peek at the regs
if (dl!=0) {
*oldhandler();
return;
}
//and down here is where i'll need to be able to modify the register values that the interrupt has to return to the caller
}

does the compiler push all the regs/segs onto the stack before handing control to my code when writing a void interrupt? if so, how can i modify them?

Chuck(G)
August 18th, 2010, 08:51 AM
It's all passed on the stack, Mike. Read up on the _interrupt keyword:


_void __interrupt __far int_handler( unsigned _es, unsigned _ds,
unsigned _di, unsigned _si,
unsigned _bp, unsigned _sp,
unsigned _bx, unsigned _dx,
unsigned _cx, unsigned _ax,
unsigned _ip, unsigned _cs,
unsigned flags )
{
. . .
}

If you're "hooking" an interrupt, you can transfer control back to the original handler using _chain_intr().

Mike Chambers
August 18th, 2010, 04:34 PM
thanks for the info. yeah, that makes a lot of sense. another thing. i've gotten pretty far working on this program today, but now i'm stuck on something. i know you can't really call an interrupt from inside another ISR, but now i need a few functions from int 21h.. in particular functions 42h(seek in file) and 3Fh(read data), there has to be SOME way to do this.

Chuck(G)
August 18th, 2010, 05:15 PM
Well, int 21H functions above 10 aren't re-entrant anyway. So, even if you check the DOS Critical-Section flag, you'll find it's set. If there was a status to pass back to DOS to say "try again later", you'd be set. But that's not the way the DOS works.

Instead of INT 13H, have you considered hooking the network redirector? Or you could hook INT 21H and decipher things yourself.

Another alternative is to read the entire image into extended/expanded memory and go from there.

Mike Chambers
August 18th, 2010, 05:28 PM
Well, int 21H functions above 10 aren't re-entrant anyway. So, even if you check the DOS Critical-Section flag, you'll find it's set. If there was a status to pass back to DOS to say "try again later", you'd be set. But that's not the way the DOS works.

Instead of INT 13H, have you considered hooking the network redirector? Or you could hook INT 21H and decipher things yourself.

Another alternative is to read the entire image into extended/expanded memory and go from there.

i had already been considering all 3 of those options, although i haven't been able to find any info on hooking the net redirector. the problem with hooking that or 21h though, is that i'd have to deal with pathname logic which is bad since i want to be able to use/modify the disk image byte for byte as if it were a physical disk in a drive.

i just had a look at function 34h on int 21h that returns the pointer of the DOS busy flag: http://www.ctyme.com/intr/rb-2739.htm

i might experiment with zeroing it right before calling what i need, and then restoring it immediately after if it was enabled. might this work? the call to the 21h function only don't work because this is set, right? if so, there shouldn't be any problem as long as the functions aren't re-entrant to 13h. i'm sure it does use functions there for the raw disk access, but my handler immediately chains to the original 13h handler if DL is anything other than 0(1st floppy) before any other code.

i WOULD like to still get info on the network redirection stuff, not for this but for a future project. i've been wanting to experiment with using an FTP server as a DOS drive. :)

Chuck(G)
August 18th, 2010, 05:38 PM
Well, you could save the DOS swap area and then clear the InDOS flag and issue your Int 21h call, then restore the InDOS and swap area memory. That should get you where you need to be.

Mike Chambers
August 18th, 2010, 05:41 PM
Well, you could save the DOS swap area and then clear the InDOS flag and issue your Int 21h call, then restore the InDOS and swap area memory. That should get you where you need to be.

DOS... swap area?

Chuck(G)
August 18th, 2010, 05:52 PM
Are you using Ralf Brown's DOS Interrupt summary? Look at INT 21H, function 5D06H "Get Address of DOS Swappable Data Area". That should tell you what you need to know.

Mike Chambers
August 18th, 2010, 06:48 PM
yeah, ralf brown's pages are amazing! think of all the cool software that probably would have never existed if it weren't for that. thanks for all the help Chuck.

Chuck smart. he lern me gud.

Chuck(G)
August 18th, 2010, 08:21 PM
Mike, if you're interested in how a network redirector works, I can forward you some code I did about 13 years to host an alien filesystem on DOS. While the file names were 8.3, the file itself is a doubly-linked list of 256 byte sectors. No FAT, you just follow the file from one sector to the next.

The code is almost all "C", but for the main program (written to avoid briging in great chunks of the C runtime that aren't needed).

PM me if you're interested and I'll pass it on.

Mike Chambers
August 20th, 2010, 08:04 AM
Mike, if you're interested in how a network redirector works, I can forward you some code I did about 13 years to host an alien filesystem on DOS. While the file names were 8.3, the file itself is a doubly-linked list of 256 byte sectors. No FAT, you just follow the file from one sector to the next.

The code is almost all "C", but for the main program (written to avoid briging in great chunks of the C runtime that aren't needed).

PM me if you're interested and I'll pass it on.

yeah i'd love to have a look. i've taken a different turn with this virtual floppy code and i've turned it into a virtual hard disk drive (over LAN). i'm working on the network routines now, but it's already fooling fdisk into thinking there's a drive. it's all int 13h and modifying the BIOS data area. wasn't planning to do any redirection because i want the system totally fooled into using it as a raw hard disk. i'd still love to see that code though.

what i'd like to do with this virtual hard disk program after getting the networking finished, is loading the boot sector via LAN and doing an actual DOS boot over the network but i need to figure out a way to make DOS not take over the memory where my program resides as well as NTCPDRV. (which might be a problem, i may have to look into WATTCP so it's all contained in my code)

Chuck(G)
August 20th, 2010, 08:15 AM
Mike, I'll PM you the location of the redirector code.

To protect the memory that your code resides in over a boot, you might just want to decrease the amount of installed memory reported in the BIOS and stuff your code up in high memory where it won't be touched.

Mike Chambers
August 22nd, 2010, 09:20 PM
that was the idea i got looking through the BIOS data area layout. the installed mem bytes. what would be the best way to go about putting my code up in that area? there must be a better solution than LH myprog.exe ...

can i just declare my procedures as a pointer at the beginning of the C code and place it up at the top of RAM or what?

Chuck(G)
August 23rd, 2010, 08:39 AM
To do this, it's even dirtier than you think.

First off, you can't have any explicit segment references in your code, other than for absolute segments, such as BIOS memory references; i.e., your code must be completely relocatable in memory. This pretty much restricts you to the tiny memory model (i.e. a .COM file).

You can calculate the top of physical conventional memory by looking at the word at 40:13h (absolute location 00413h). Usually, it will be 280H (decimal 640) and represents the number of kilobytes (1024) of conventional RAM. Figure out how many K your program will occupy and calculate the new top of memory and adjust 00413H accordingly.

Disable interrupts and move your program (or at least the part of it that you'll need) up to the area that you've reserved. If your program needs to "hook" any interrupts, do that, but be sure that the "hook" points to the copy of your program in high memory. (in your case, int 13h).

Clear ES and DS and execute an INT 19H, which will cause the system to enter its OS load routine.

Note that you have to do this with a "plain" copy of DOS; no installed drivers, etc. that might leave "hooks" of BIOS interrupts pointing to nowhere after rebooting. You could even make your driver as its own boot record (i.e. no DOS at all) if you wanted.

Mike Chambers
August 26th, 2010, 03:13 PM
i've been thinking about the relocation of my code in memory, and here's what i came up with.. tiny mode not required. at least, i think my theory here is solid. let me know if not.

i'm going to write a small loader program that first gets the RAM size from the BIOS data area, subtracts what i needs and tosses it back into the BDA. then manually parse the EXE header for my main program and the load it directly to the memory segment i determined. next, process each relocation entry from the header and adjust values appropriately. set SS, SP, DS, ES appropriately. then i could PUSH correct values for CS:IP to the stack and POP em with a far RET. afaik, this should work.

as far as actually booting an OS after my LAN Drive software gets configured and fakes a fixed disk, i'd just have it read the first sector from whichever device i want to boot from. user can choose, and even the remote network disk should work since i'll have taken over int 13h. i'd check for a valid boot record signature word, and if it is there stuff the sector into 0000:7C00 and jump.

i suppose i could make two versions of the loader, one as a standalone bootloader and another for DOS. thoughts? i'm taking this project very seriously, because it would kick ass. :)

Chuck(G)
August 26th, 2010, 04:10 PM
You may get DOS to do most of the work for you. Try DOS function 4B03h, for example, which allows you to specify both a starting segment and a relocation factor.

Mike Chambers
August 26th, 2010, 11:15 PM
yeah, that'd be a nice way to test it. however, all my google-fu skills arent helping me bring up any info on that particular function. it doesn't even seem to be in the ralf brown list on ctyme.com

mbbrutman
August 27th, 2010, 04:15 AM
Mike,

You really need a copy of 'Undocumented DOS, 2nd Edition' ...


Mike

Chuck(G)
August 27th, 2010, 07:59 AM
yeah, that'd be a nice way to test it. however, all my google-fu skills arent helping me bring up any info on that particular function. it doesn't even seem to be in the ralf brown list on ctyme.com

Sure it is--it's just not stated the usual way (I don't know why):

http://www.ctyme.com/intr/rb-2939.htm

Look at the various options for AL.