digitalmars.D - Get memory address of a function?
- Braden MacDonald (35/35) May 25 2004 Hi Everyone,
- Walter (5/35) May 25 2004 What you're doing should work fine. I suspect something else is going on...
- David L. Davis (5/47) May 26 2004 Braden, I'm looking at the Intel 386 Asm Manual, and it states, "CR2 is ...
- David L. Davis (15/62) May 26 2004 Post1: Braden, I'm looking at the Intel 386 Asm Manual, and it states, "...
- Braden MacDonald (58/72) May 26 2004 Thanks, I have it working now (see my reply to Walter).
- Braden MacDonald (28/65) May 26 2004 You were right. If both functions were members of the same struct, then ...
- Andy Friesen (5/24) May 26 2004 You'll have to make f2 static. As it stands, &f2 is 8 bytes long, not
- Braden MacDonald (5/8) May 27 2004 pointer to the Something instance, four more for the
- Walter (5/23) May 27 2004 Make it a static member function, and you can take the address of it jus...
Hi Everyone, How can I access the memory address of a function? I want the address for loading into an Interrupt Descriptor Table. example : void enableInterrupts( ... ) { ... tables[14].handler=cast(void*)&_interrupt14; // This generates an error - e2ir: cannot cast from void delegate() to void* .. } void _interrupt14() { asm { pusha; push DS; push ES; push FS; push GS; mov EAX,CR2; push EAX; call interrupt14; pop GS; pop FS; pop ES; pop DS; popa; iret; } } void interrupt14() { // Handler } Thanks a lot! Braden
May 25 2004
What you're doing should work fine. I suspect something else is going on in the omitted code. Try boiling it down to the minimum. "Braden MacDonald" <bradenm_k shaw.ca> wrote in message news:c91951$i1s$1 digitaldaemon.com...Hi Everyone, How can I access the memory address of a function? I want the address for loading into an Interrupt Descriptor Table. example : void enableInterrupts( ... ) { ... tables[14].handler=cast(void*)&_interrupt14; // This generates an error - e2ir: cannot cast from void delegate() tovoid*.. } void _interrupt14() { asm { pusha; push DS; push ES; push FS; push GS; mov EAX,CR2; push EAX; call interrupt14; pop GS; pop FS; pop ES; pop DS; popa; iret; } } void interrupt14() { // Handler } Thanks a lot! Braden
May 25 2004
In article <c91cfg$mjj$1 digitaldaemon.com>, Walter says...What you're doing should work fine. I suspect something else is going on in the omitted code. Try boiling it down to the minimum. "Braden MacDonald" <bradenm_k shaw.ca> wrote in message news:c91951$i1s$1 digitaldaemon.com...Braden, I'm looking at the Intel 386 Asm Manual, and it states, "CR2 is used for handling page faults when PG (CR0, Paging, bit 31) is set. The processor stores in CR2 the linear address that triggers the fault." Since I don't see CR0 bit 31 being set in your above code...maybe that's it. ;)Hi Everyone, How can I access the memory address of a function? I want the address for loading into an Interrupt Descriptor Table. example : void enableInterrupts( ... ) { ... tables[14].handler=cast(void*)&_interrupt14; // This generates an error - e2ir: cannot cast from void delegate() tovoid*.. } void _interrupt14() { asm { pusha; push DS; push ES; push FS; push GS; mov EAX,CR2; push EAX; call interrupt14; pop GS; pop FS; pop ES; pop DS; popa; iret; } } void interrupt14() { // Handler } Thanks a lot! Braden
May 26 2004
In article <c92s45$2ude$1 digitaldaemon.com>, David L. Davis says...In article <c91cfg$mjj$1 digitaldaemon.com>, Walter says...Post1: Braden, I'm looking at the Intel 386 Asm Manual, and it states, "CR2 is used for handling page faults when PG (CR0, Paging, bit 31) is set. The processor stores in CR2 the linear address that triggers the fault." Since I don't see CR0 bit 31 being set in your above code...maybe that's it. ;) Post2: Braden, it looks like I may have misread your problem...sorry. To set up a pointer to a function in D: // Creates a void function pointer with void // parameters, this matchs void _interrupt14() void function( ) pt2Function; // Assigns the function's address to the pointer pt2Function = &_interrupt14; // Then can call the function thru the point pt2Function(); Hope I got it right this time?What you're doing should work fine. I suspect something else is going on in the omitted code. Try boiling it down to the minimum. "Braden MacDonald" <bradenm_k shaw.ca> wrote in message news:c91951$i1s$1 digitaldaemon.com...Hi Everyone, How can I access the memory address of a function? I want the address for loading into an Interrupt Descriptor Table. example : void enableInterrupts( ... ) { ... tables[14].handler=cast(void*)&_interrupt14; // This generates an error - e2ir: cannot cast from void delegate() tovoid*.. } void _interrupt14() { asm { pusha; push DS; push ES; push FS; push GS; mov EAX,CR2; push EAX; call interrupt14; pop GS; pop FS; pop ES; pop DS; popa; iret; } } void interrupt14() { // Handler } Thanks a lot! Braden
May 26 2004
Post2: Braden, it looks like I may have misread your problem...sorry. To setupa pointer to a function in D: // Creates a void function pointer with void // parameters, this matchs void _interrupt14() void function( ) pt2Function; // Assigns the function's address to the pointer pt2Function = &_interrupt14; // Then can call the function thru the point pt2Function(); Hope I got it right this time?Thanks, I have it working now (see my reply to Walter). As you may have guessed, I'm writing an operating system in D. I already have paging set up and working, and I have a kmalloc/free working as well. What I'm trying to do now is set up interrupt handling (especially Page Fault) - which has proved more difficult than it first appeared. Do you happen to know how to use the "lidt" assembler instruction from D? I thought that it took a pointer to a 6-byte structure, but my code will only compile if I pass it a 64-bit paramater: /* Pointer to IDT table: */ struct idtPtr { ushort length=256*8-1; //Size of table uint addr; // Actual pointer to first entry } void enableInterrupts() { IDTEntry[256]* base = cast(IDTEntry[256]*)kmalloc(IDTEntry.size*256); idtPtr p; p.addr = cast(uint)&((*base)[0]); for (int i=0;i<256;i++) { .. // fill IDT table pointed to by "base" } /* Now, load the table into the CPU register: */ asm { lidt p; } /* Now our interrupt handler should be working. (but it isn't) */ } /* One Interrupt Descriptor Entry: */ struct IDTEntry { ushort _handlerH;//High 16 bits of handler address ushort _flags=0; ushort _segment; ushort _handlerL; void handler(void* addy) { _handlerH = cast(uint)addy>>16; _handlerL = cast(uint)addy & 0x0000FFFF; } void* handler() { return cast(void*)((_handlerH<<16) | (_handlerL)); } void segment(ushort s) { _segment=s; } void present(bit p) { if (p) {_flags |= 1<<15;} else { _flags &= 0xFFFF ^(1<<15); } } bit present() { return (_flags & (1<<15)) != 0; } void kernel(bit kernel) { if (!kernel) { _flags = _flags | 3<<13; } else { _flags &= 0xFFFF ^ (3<<13); } } bit kernel() { return (_flags & (3<<13)) != 0; } void type(bit interrupt/* opposed to trap*/) { _flags &= (0xFFFF) ^ (15<<8); if (interrupt) { _flags |= 14<<8; } else { _flags |= 15<<8; } } } ___ This code (extracted from my kernel) doesn't work - because any (or all) of several things could be wrong, I'm not sure which to change. Any ideas? Thanks a lot!
May 26 2004
You were right. If both functions were members of the same struct, then it won't compile. If I make _interrupt14 global, then it compiles fine. Is there any way around this? I'd rather not have a global function if possible. ___________________________________ struct Something { void f1() { void* p2 = cast(void*)&_f2; // Error void* p3 = cast(void*)&_f3; // OK } void f2() { //Something } } void f3() { //Something } ___________________________________ In article <c91cfg$mjj$1 digitaldaemon.com>, Walter says...What you're doing shouldwork fine. I suspect something else is going on inthe omitted code. Tryboiling it down to the minimum."Braden MacDonald" <bradenm_k shaw.ca>wrote in messagenews:c91951$i1s$1 digitaldaemon.com...How can I access the memory address of a function? I want theHi Everyone,address for loading into an Interrupt Descriptor Table. example : void enableInterrupts( ... ) { ... tables[14].handler=cast(void*)&_interrupt14; // This generates an error - e2ir: cannot cast from void delegate() tovoid*.. } void _interrupt14() { asm { pusha; push DS; push ES; push FS; push GS; mov EAX,CR2; push EAX; call interrupt14; pop GS; pop FS; pop ES; pop DS; popa; iret; } } void interrupt14() { // Handler }Thanks a lot! Braden
May 26 2004
Braden MacDonald wrote:You were right. If both functions were members of the same struct, then it won't compile. If I make _interrupt14 global, then it compiles fine. Is there any way around this? I'd rather not have a global function if possible. ___________________________________ struct Something { void f1() { void* p2 = cast(void*)&_f2; // Error void* p3 = cast(void*)&_f3; // OK } void f2() { //Something } } void f3() { //Something }You'll have to make f2 static. As it stands, &f2 is 8 bytes long, not four. (four for a pointer to the Something instance, four more for the address of the method) -- andy
May 26 2004
In article <c93gig$qv9$1 digitaldaemon.com>, Andy Friesen says...You'll haveto make f2 static. As it stands, &f2 is 8 bytes long, notfour. (four for apointer to the Something instance, four more for theaddress of the method)Right. Thanks for for the explanation, that part compiles fine now. (My IDT still isn't working, though - see my other email)
May 27 2004
Make it a static member function, and you can take the address of it just like a global function. "Braden MacDonald" <bradenm_k shaw.ca> wrote in message news:c93fh9$pme$1 digitaldaemon.com...You were right. If both functions were members of the same struct, then it won't compile. If I make _interrupt14 global, then it compiles fine. Isthereany way around this? I'd rather not have a global function if possible. ___________________________________ struct Something { void f1() { void* p2 = cast(void*)&_f2; // Error void* p3 = cast(void*)&_f3; // OK } void f2() { //Something } } void f3() { //Something }
May 27 2004