how do we call assembly function in c?

3

Hello :) i got a serious problem to call my assembly function in my c program, it said that it's undefined reference.

here my assembly code :

[GLOBAL gdt_flush]

gdt_flush:
    mov eax, [esp+4]  ; Get the pointer to the GDT, passed as a parameter.
    lgdt [eax]        ; Load the new GDT pointer

    mov ax, 0x10      ; 0x10 is the offset in the GDT to our data segment
    mov ds, ax        ; Load all data segment selectors
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ss, ax
    jmp 0x08:.flush   ; 0x08 is the offset to our code segment: Far jump!
.flush:
    ret

then my c code : my file where i put the call of the function :

#include <k/types.h>
#include "io.h"
#include "init_tables.h"
#include "events.h"


extern void gdt_flush(u32 gdt_ptr);

/* 1. SERIAL PORT */
void init_uart(void)                //Initialize uart 16550 for 38400 bps
{
    u8 ier = inb(SERIAL_PORT + 1);
    u8 fcr = inb(SERIAL_PORT + 2);
    u8 lcr = inb(SERIAL_PORT + 3);
    u16 rate = 38400;

    outb(SERIAL_PORT + 3, lcr | 1 << 7);
    outb(SERIAL_PORT + 0, (115200 / rate) & 255); // = 0x3
    outb(SERIAL_PORT + 1, (115200 / rate) >> 8);  // = 0x0
    outb(SERIAL_PORT + 3, lcr & ~(1 << 7));

    outb(SERIAL_PORT + 2, fcr | 1 << 1);
    outb(SERIAL_PORT + 2, fcr | 1 << 2);
    outb(SERIAL_PORT + 2, fcr | 1 << 6);
    outb(SERIAL_PORT + 2, fcr | 1 << 7);
    outb(SERIAL_PORT + 1, ier | 1 << 1);
}

/* 2. MEMORY MANAGER */

static struct gdt_entry gdt[5];
static struct gdt_r gdt_r;

static void set_gdt_entry(unsigned index, u32 base_adress, u32 limit, u16 access, u16 flags)/* Function to initialize an index of the gtd_entry structure */
{
    if (index >= SIZE_ARRAY(gdt))
        printf("ARRAY SIZE INCORRECT\n");

    gdt[index].seg_lim_15_00 = (limit & 0xFFFF); // set segment limit of 00-15
    gdt[index].granularity = (limit >> 16) & 0x0F; // set segment of 16-19 
    gdt[index].granularity |= flags & 0xF0; // granularity, operand size, zero and avl  -> flags

    gdt[index].access_byte = access; //set up type, s, dpl, p 

    gdt[index].base_15_00 = (base_adress & 0xFFFF); //set up base 00-15 bit
    gdt[index].base_23_16 = (base_adress >> 16) & 0xFF; //set up base 16-23 bit
    gdt[index].base_31_24 = (base_adress >> 24) & 0xFF; //set up base 24-31 bit

}


static void gdt_load(void)        /* Function to load our gtd and reload segment selectors*/
{
    __asm__ volatile ("lgdt %[gdt_r]\n"
                      "mov  %%cr0, %%eax\n"
                      "or      $1, %%eax\n"
                      "mov  %%eax, %%cr0\n"
                      "mov  %[ds], %%ax\n"
                      "mov   %%ax, %%ds\n"
                      "mov   %%ax, %%es\n"
                      "mov   %%ax, %%fs\n"
                      "mov   %%ax, %%gs\n"
                      //"mov   %%ax, %%ss\n"
                      "ljmp %[cs], $set_cs\n"
                      "set_cs:\n"
                      :
                      : [gdt_r]"m"(gdt_r), [cs]"i"(0x8), [ds]"i"(0x10)
                      : "%eax");


    /*asm volatile(" lgdt %0\n" : : "m"(gdt_r) : "memory"); //LOAD GTD

    asm volatile ("movl %cr0, %eax\n\t" // activate protected mode
                  "or %al, 1\n\t"
                  "movl %eax, %cr0\n\t"
                  "movw $0x10, %ax\n\t"
                  "movw %ax, %ds\n\t"
                  "movw %ax, %es\n\t"
                  "movw %ax, %fs\n\t"
                  "movw %ax, %gs\n\t"
                  "movw %ax, %ss\n\t"
                  "ljmp $0x08, $1f\n\t"
                  "1:\n\t");*/

}

static void init_gdt(void)
{
    gdt_r.limit = sizeof(gdt) - 1;
    gdt_r.base  = (u32)&gdt;

    set_gdt_entry(0, 0, 0, 0, 0);                /* Null segment */
    set_gdt_entry(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); /* Code segment */
    set_gdt_entry(2, 0, 0xFFFFFFFF, 0x92, 0xCF); /* Data segment */
    //set_gdt_entry(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); /* User mode code segment */
    //set_gdt_entry(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); /* User mode data segment */

    gdt_flush((u32)&gdt_r);
    //gdt_load();
}

void init_kernel(void)
{
    init_uart();
    init_gdt();
    //init_interrupt();
    //load_idt();
    //print_stack();
}

then my Makefile :

#
# Copyright (c) LSE
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY LSE AS IS AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL LSE BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
include ../config.mk

TARGET  = k
OBJS    = \
      crt0.o \
      k.o \
      libvga.o \
      list.o \
      memory.o \
      io.o \
      init_tables.o \
      #events.o
      #isr.o


DEPS = $(OBJS:.o=.d)

all: $(TARGET)

$(TARGET): CPPFLAGS += -MMD -Iinclude -I ../libs/libc/include/
$(TARGET): CFLAGS += $(K_EXTRA_CFLAGS)
$(TARGET): LDFLAGS += -Wl,-Tk.lds
$(TARGET): LDLIBS = -L../libs/libc -lc
$(TARGET): $(OBJS) init_tables.s

install: $(TARGET)
    $(INSTALL) $(TARGET) $(INSTALL_ROOT)/$(TARGET)

clean:
    $(RM) $(OBJS) $(DEPS) $(TARGET)

-include $(DEPS)

Right now i put a gas file to be execute at the loading so i can't understand why it doesnt work and why i need to link these files. I was sure that the link is doing it automatically Can somebody help me ? Thanks a lot :)

c
assembly
x86
kernel
asked on Stack Overflow Oct 27, 2020 by YoloSama • edited Oct 27, 2020 by YoloSama

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0