inline wird zu einer richtigen Funktion
-
Hallöchen,
ich hab da ein kleines Problem. Hier mal "mein" Code:
// ckernel.c //void *someOperation(void *parameter1, int parameter2); inline void outportb(unsigned short port,unsigned short value) { //__asm xor rax, rax __asm mov ax, value; __asm mov dx, port; __asm out dx, ax; } void k_clear_screen() { char* vidmem = (char*) 0xb8000; unsigned int i = 0; while(i < (80 * 2 * 25)) { vidmem[i] = ' '; ++i; vidmem[i] = 0x07; ++i; } } unsigned int k_printf(char* message, unsigned int line) { char* vidmem = (char*) 0xb8000; unsigned int i = line *80 * 2; while(*message != 0) { if(*message == 0x2F) { *message++; if(*message == 0x6e) { line++; i = (line * 80 * 2); *message++; if(*message == 0) { return(1); } } } vidmem[i] = *message; *message++; ++i; vidmem[i] = 0x7; ++i; } return 1; } void update_cursor(int row, int col) { unsigned short position = (row * 80) + col; // cursor LOW port to vga INDEX register outportb(0x3D4, 0x0F); outportb(0x3D5, (unsigned short)(position & 0xFF)); // cursor HIGH port to vga INDEX register outportb(0x3D4, 0x0E); outportb(0x3D5, (unsigned short)((position >> 8) & 0xFF)); } int main() { //void *arg1 = (void*)0x80001000; //int arg2 = 12; //void *returnValue = someOperation(arg1, arg2); //try //{ k_clear_screen(); k_printf("Welcome to HenkesSoft OS.", 0); k_printf("The C kernel has been loaded.", 2); update_cursor(3, 0); return 0; // } //catch(...) //{ // return 1; //} }
Problem ist nun, dass die mit inline gekenzeichnete "Funktion" nicht wie erwartet in die entsprechenden Zeilen eingefügt wird, sondern das der Compiler da eine eigene Funktion draus macht. Bin ich dämlich?! Wo liegt der Fehler??
-
Inline ist nur eine Empfehlung, der Compiler muss solche Funktionen nicht inlinen.
-
inline kam mit C99 und ist gemäß dem Standard nicht zwingend.
Der Compiler kann es umsetzen oder auch nicht (wie wohl bei dir), ähnlich zu register.
-
Öh, wie kann ich den denn dazu zwingen?! Immerhin wird da jede Menge Zeugs abgearbeitet für die paar Zeilen Assembler. Sprich, Stackframe...
-
Sorry, zu spät gesehen;-)
Schade:-( Naja, dann schreibe ich es eben von Hand rein..
-
Wenn du MSVC benutzt kannst du __forceinline verwenden. GCC hat __attribute__((always_inline)).
-
Nur um dämliche Fehler zu vermeiden: Optimierungen hast du aber eingeschaltet, oder? Moderne Compiler sind eigentlich recht aggressive Inliner, daher wundert mich das schon sehr stark bei so einer Minifunktion. Beim GCC würde ich sogar erwarten, dass dein ganzes Programm zu einer einzigen Funktion zusammengefasst wird. Bin aber gerade zu faul, dein Assembler auf die GCC-Syntax umzuschreiben, um das zu testen.
-
SeppJ schrieb:
Moderne Compiler sind eigentlich recht aggressive Inliner
Jop, VS inlinet alles:
int main() { 00081000 push ebp 00081001 mov ebp,esp 00081003 push ecx 00081004 push ebx 00081005 push esi //void *arg1 = (void*)0x80001000; //int arg2 = 12; //void *returnValue = someOperation(arg1, arg2); //try //{ k_clear_screen(); 00081006 mov eax,0B8000h 0008100B mov bl,7 0008100D lea ecx,[ecx] 00081010 mov byte ptr [eax],20h 00081013 mov byte ptr [eax+1],bl 00081016 add eax,2 00081019 cmp eax,0B8FA0h 0008101E jb main+10h (81010h) k_printf("Welcome to HenkesSoft OS.", 0); 00081020 xor edx,edx 00081022 mov ecx,offset string "Welcome to HenkesSoft OS." (87810h) 00081027 mov al,57h 00081029 xor esi,esi 0008102B jmp main+30h (81030h) 0008102D lea ecx,[ecx] 00081030 cmp al,2Fh 00081032 jne main+4Ch (8104Ch) 00081034 mov al,byte ptr [ecx+1] 00081037 inc ecx 00081038 cmp al,6Eh 0008103A jne main+4Ch (8104Ch) 0008103C mov al,byte ptr [ecx+1] 0008103F inc ecx 00081040 add esi,0A0h 00081046 mov edx,esi 00081048 test al,al 0008104A je main+62h (81062h) 0008104C mov byte ptr [edx+0B8000h],al 00081052 inc ecx 00081053 mov byte ptr [edx+0B8001h],bl 00081059 mov al,byte ptr [ecx] 0008105B add edx,2 0008105E test al,al 00081060 jne main+30h (81030h) k_printf("The C kernel has been loaded.", 2); 00081062 mov edx,140h 00081067 mov ecx,offset string "The C kernel has been loaded." (8782Ch) 0008106C mov al,54h 0008106E mov esi,edx 00081070 cmp al,2Fh 00081072 jne main+8Ch (8108Ch) 00081074 mov al,byte ptr [ecx+1] 00081077 inc ecx 00081078 cmp al,6Eh 0008107A jne main+8Ch (8108Ch) 0008107C mov al,byte ptr [ecx+1] 0008107F inc ecx 00081080 add esi,0A0h 00081086 mov edx,esi 00081088 test al,al 0008108A je main+0A2h (810A2h) 0008108C mov byte ptr [edx+0B8000h],al 00081092 inc ecx 00081093 mov byte ptr [edx+0B8001h],bl 00081099 mov al,byte ptr [ecx] 0008109B add edx,2 0008109E test al,al 000810A0 jne main+70h (81070h) update_cursor(3, 0); 000810A2 mov ax,0Fh 000810A6 mov dx,3D4h 000810AA out dx,ax 000810AC mov dword ptr [ebp-4],0F0h 000810B3 mov ax,word ptr [ebp-4] 000810B7 mov dx,3D5h 000810BB out dx,ax 000810BD mov ax,0Eh 000810C1 mov dx,3D4h 000810C5 out dx,ax 000810C7 mov dword ptr [ebp-4],0 000810CE mov ax,word ptr [ebp-4] 000810D2 mov dx,3D5h 000810D6 out dx,ax 000810D8 pop esi return 0; 000810D9 xor eax,eax 000810DB pop ebx // } //catch(...) //{ // return 1; //} } 000810DC mov esp,ebp 000810DE pop ebp 000810DF ret