簡體   English   中英

如何從匯編代碼調用 C 函數

[英]How to call a C function from Assembly code

我在從匯編代碼轉換為 C 時遇到了麻煩。我通過將內核放在第二階段引導加載程序的填充之后並增加要在第一階段引導加載程序中加載的扇區數以某種方式加載了我的內核。 正如你在這里看到的:

boot1.asm:

;----------------------------------------------;
;
; The BoneOS Stage 1 Bootloader
; -----------------------------
;
;
; Contributors : @amanuel2
;
;
;----------------------------------------------;

[ORG 0x7c00]   ;We Will Set Registers to point to 0x7C00 Later

[  BITS  16  ]; 16 bits real mode

JMP main_first ; Jump to Main Function of the Bootloader

 ;/////////////////////////////////////////////
 ;  Include Files
 ;////////////////////////////////////////////

     ;--------------------------------------
     ;      STDIO.h
     ; I/O Functions. Such as printfb which 
     ; prints a string to the screen.
     ; 
     ; @functions:
     ;     printfb ARGS: <SI = String>
     ;     printfbln ARGS: <SI = String>
     ;     clearscreen
     ;     print_new_line
     ;--------------------------------------
     %include "stdiobios.inc" 

;-----------------------------------------------
;-----------------------------------------------
;  Label "Function" Main Declarations :)
; 
;   Bone Project
;----------------------------------------------




;----------------------------------------------
;  Label "Variable" Main Declaractions :)
;
;  Bone Project
;----------------------------------------------

FirstMessageExecution : db "Stage 1 Bootloader Executing .  .  .", 0
SECONDSTAGEXECUTION : db "Stage 2 Bootloader Executing . . .",0

;align 4
gdt_start:                              ; Start of global descriptor table
    gdt_null:                           ; Null descriptor chunk
        dd 0x00
        dd 0x00
    gdt_code:                           ; Code descriptor chunk
        dw 0xFFFF
        dw 0x0000
        db 0x00
        db 0x9A
        db 0xCF
        db 0x00
    gdt_data:                           ; Data descriptor chunk
        dw 0xFFFF
        dw 0x0000
        db 0x00
        db 0x92
        db 0xCF
        db 0x00
    gdt_end:                            ; Bottom of table
gdt_descriptor:                         ; Table descriptor
    dw gdt_end - gdt_start - 1          ; Size of table
    dd gdt_start                        ; Start point of table

gdt_codeSeg equ gdt_code - gdt_start    ; Offset of code segment from start
gdt_dataSeg equ gdt_data - gdt_start    ; Offset of data segment from start

    a20wait:
        in   al,0x64 ; input from 0x64 port, goes to al register
        test    al,2 ; compares al register with 2
        jnz     a20wait ; If it is zero loop again
        ret


    a20wait2:
        in      al,0x64 ; input from 0x64 port, goes to al register
        test    al,1 ; compares al register with 2
        jz      a20wait2 ; If it is zero loop again
        ret 

                                                ;-----                              -----;
                                                ;-----      Main Function           -----;
                                                ;-----                              -----;


main_first:  
                CLI ; Clear Interupts Before Manupulating Segments

                ;------------------------------
                ; Bootloader Repsonsibility To 
                ; Setup Registers to point to our 
                ; Segments (Except Code Segment)
                ;
                ;------------------------------

SEGMENTS:               
                ; 0x0000 : 0x7c00 
                xor ax,ax ; 0x0000
                MOV ds,ax ; Data Segment
                MOV es,ax ; Extra Segment (E)
                MOV fs,ax ; Extra Extra Segment (F Comes after E)
                MOV gs,ax ; Extra Extra Extra Segment (G Comes after F)

                ;-------------------------------
                ;--Setting Up The Stack
                ;--Stack Grows Downwards
                ;-------------------------------

STACK:              
                MOV ax,0
                MOV ss,ax ; Cant Directly MOVe to Stack Segment
                MOV sp,0xFFFE ; Start Stackpointer from the top, growing downward


                STI ; Restore Interupts
                MOV     ax, 0x3
                INT     0x10    

SECONDSTAGE:        
                MOV si, FirstMessageExecution
                CALL printfbln      

                ; Load stage 2 to memory.
                MOV ah, 0x02
                ; Number of sectors to read.
                MOV al, 20
                ; This may not be necessary as many BIOS set it up as an initial state.
                MOV dl, 0x00
                ; Cylinder number.
                MOV ch, 0
                ; Head number.
                MOV dh, 0
                ; Starting sector number 2 because 1 was already loaded.
                MOV cl, 2
                ; Where to load to.
                MOV bx, stage2
                INT 0x13

                JMP stage2

                ; Magic bytes.    
                times ((0x200 - 2) - ($ - $$)) db 0x00
                dw 0xAA55


;--------------------------------------
;       load2.asm
;   Second Stage Bootloader
;   Which then loads the kernel
;   in 32 bit protected mode!
;   
;--------------------------------------
%include "boot2.asm"

boot2.asm:

;----------------------------------------------;
;
; The BoneOS Stage 2 Bootloader
; -----------------------------
;
;
; Contributors : @amanuel2
;
;
;----------------------------------------------;



  stage2:

    MOV si, SECONDSTAGEXECUTION
    CALL printfbln  


    ; enable A20 gate
    enable_A20: ; Enabling A20 Line For Full Memory
            cli ; Stop Interupts before doing so

            call    a20wait ; a20wait call
            mov     al,0xAD ; Send 0xAD Command to al register
            out     0x64,al ; Send command 0xad (disable keyboard).

            call    a20wait ; When controller ready for command
            mov     al,0xD0 ; Send 0xD0 Command to al register
            out     0x64,al ; Send command 0xd0 (read from input)

            call    a20wait2 ; When controller ready for command
            in      al,0x60 ; Read input from keyboard
            push    eax ; Save Input by pushing to stack

            call    a20wait ; When controller ready for command
            mov     al,0xD1 ; mov 0xD1 Command to al register
            out     0x64,al ; Set command 0xd1 (write to output)

            call    a20wait ; When controller ready for command
            pop     eax ; Pop Input from Keyboard
            or      al,2 ; Mov 0xD3 to al register
            out     0x60,al ; Set Command 0xD3

            call    a20wait ; When controller ready for command
            mov     al,0xAE ; Mov Command 0xAE To al register
            out     0x64,al ; Write command 0xae (enable keyboard)

            call    a20wait ; When controller ready for command
            sti ; Enable Interrupts after enabling A20 Line


    ;load a GDT
    ; enter pmode
    loadgdt:
        cli             ; disable int
        LGDT [gdt_descriptor]                   ; Load global descriptor table for protected mode

        mov EAX, CR0                            ; Move CR0 to GP register
        or EAX, 0x1                             ; Set first bit to switch to protected mode
        mov CR0, EAX                            ; Update CR0 from GP register to complete switch



        ;JMP gdt_codeSeg:start32                 ; Jump to start of 32-bit code
        jmp 0x08:stage3 ; go to 32-bit code

        %include "boot3.asm"


    times ((0x400) - ($ - $$)) db 0x00

    %include "kernel.asm"

boot3.asm:

;----------------------------------------------;
;
; The BoneOS Bootloader Third Stage Bootloader
; ------------------------------
;
;
; Contributors : @amanuel2
;
;
;----------------------------------------------;

%include "stdio32boot.inc"

[BITS 32]

        stage3:
          ; set segment registers
          mov ax, 0x10
          mov ds, ax
          mov ss, ax

          mov esp, 0x090000 ; set up stack pointer

          push 'A'
          call puts32char
          add esp, 4
             jmp 0x08:k_main
            cli
            loopend:                ;Infinite loop when finished
                hlt
          jmp loopend

          cli
          hlt

內核.asm:

 ;ORG 0x9000
BITS 32

k_main:
    mov byte [0xB8000], 88
    mov byte [0xB8000+1], 0x1B


    mov byte [0xB8000+4], 89
    mov byte [0xB8000+5], 0x1B
    cli
    hlt

如您所見,我從引導加載程序加載了內核,現在在 Assembly 中一切正常,但我的問題出現了:如何讓kernelc_main從 Assembly 中調用像kernelc_main這樣的 C 函數?

你可以嘗試這樣做:

在 C 中創建一個類

void kmain()
{
//Do here.....
}

上面的代碼在 C 中創建了一個名為“kmain”的類

現在,在你的匯編代碼中,

ORG 0x9000
BITS 32
extern kmain
k_main:
    mov byte [0xB8000], 88
    mov byte [0xB8000+1], 0x1B


    mov byte [0xB8000+4], 89
    mov byte [0xB8000+5], 0x1B
    call kmain
    cli
    hlt

語法“extern”用於在程序集中包含外部函數或類。 然后你可以使用普通的“調用”來調用內核。

希望這個回答有用,謝謝

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM