C 使用EXTERN使用混合代码的引导加载程序

C 使用EXTERN使用混合代码的引导加载程序,c,assembly,nasm,boot,C,Assembly,Nasm,Boot,我正在bootloader上创建简单的计算器应用程序,使用混合代码,包括C语言和汇编代码 我的C语言代码是(addasm.C): #包括 int main() { bootmain(); return 0 ; } int bootmain() { int arg1, arg2, add, sub, mul, quo, rem ; printf( "Enter two integer numbers : " ); scanf( "%d%d", &arg1,

我正在bootloader上创建简单的计算器应用程序,使用混合代码,包括C语言和汇编代码

我的C语言代码是(addasm.C): #包括

      int main() {

bootmain();
return 0 ;

  }
   int bootmain()
  {
 int arg1, arg2, add, sub, mul, quo, rem ;

printf( "Enter two integer numbers : " );
scanf( "%d%d", &arg1, &arg2 );

/* Perform Addition, Subtraction, Multiplication & Division */
__asm__ ( "addl %%ebx, %%eax;" : "=a" (add) : "a" (arg1) , "b" (arg2) );
__asm__ ( "subl %%ebx, %%eax;" : "=a" (sub) : "a" (arg1) , "b" (arg2) );
__asm__ ( "imull %%ebx, %%eax;" : "=a" (mul) : "a" (arg1) , "b" (arg2) );

__asm__ ( "movl $0x0, %%edx;"
          "movl %2, %%eax;"
          "movl %3, %%ebx;"
           "idivl %%ebx;" : "=a" (quo), "=d" (rem) : "g" (arg1), "g" (arg2) );

printf( "%d + %d = %d\n", arg1, arg2, add );
printf( "%d - %d = %d\n", arg1, arg2, sub );
printf( "%d * %d = %d\n", arg1, arg2, mul );
printf( "%d / %d = %d\n", arg1, arg2, quo );
printf( "%d %% %d = %d\n", arg1, arg2, rem );
return 0;
 }
我已经用C语言创建了bootmain()函数,我需要在汇编代码中使用它

我的汇编代码(ccode.asm)是:

现在我正在编译这个

    nasm -f elf -o main.o ccode.asm  #assemble our asm file
但它给我的组织关键字的错误,它是未定义的关键字

如果我将删除这个关键字,那么它将为我提供无错误的输出

删除ORG关键字后,我将按以下方式编译:

  nasm -f elf -o main.o ccode.asm  #assemble our asm file
  gcc addasm.c main.o -o add_asm     #compile and link in one step
  ./add_asm                       
因此,我正在使用这个最终的add_asm文件,并通过使用磁盘资源管理器放置这个add_asm文件来启动我的usb驱动器。 但在启动时,它显示的信息是:缺少操作系统 所以,这是一个在程序集文件中不使用组织的问题。 这是我在NASM中使用的ELF的主要问题。但是对于外部C函数和EXTERN关键字,我需要使用ELF

组织的备选代码为:

  [Bits 16]
  extern bootmain
  start:
  mov ax, 07C0h ; Set up 4K stack space after this bootloader
  add ax, 288 ; (4096 + 512) / 16 bytes per paragraph
  mov ss, ax
  mov sp, 4096
 call bootmain
 mov ax, 07C0h ; Set data segment to where we're loaded
 mov ds, ax
 times 510-($-$$) db 0; Pad remainder of boot sector with 0s
 dw 0xAA55 ; The standard PC boot signature
但它也不起作用。。。它给我的错误和启动时的“缺少操作系统”一样


在汇编文件(*.asm)中包含C函数还有其他方法吗? 我被困在这里了。如果有什么建议,请给我。
谢谢。

你不能把普通的C程序变成那样的引导程序

  • 引导加载程序运行的环境与普通可执行文件有很大不同。特别是,它不包括可以链接的C库(或者,就此而言,任何链接器!),因此像
    printf()
    scanf()
    这样的函数都不可用,除非您链接到适当的版本,而您没有这样做

  • 您正在将程序编译为32位可执行文件。x86系统以16位模式启动。要切换到该模式,必须进行大量初始化,这里没有任何初始化

  • 您正在将程序编译为Linux ELF(或者可能是Windows PE?)可执行文件。这不是引导加载程序的正确格式


    • 您无法将普通的C程序转换为那样的引导加载程序

      • 引导加载程序运行的环境与普通可执行文件有很大不同。特别是,它不包括可以链接的C库(或者,就此而言,任何链接器!),因此像
        printf()
        scanf()
        这样的函数都不可用,除非您链接到适当的版本,而您没有这样做

      • 您正在将程序编译为32位可执行文件。x86系统以16位模式启动。要切换到该模式,必须进行大量初始化,这里没有任何初始化

      • 您正在将程序编译为Linux ELF(或者可能是Windows PE?)可执行文件。这不是引导加载程序的正确格式


      是否有其他方法在汇编文件(*.asm)中包含C函数?您似乎感到困惑。NASM不是C编译器。它不能编译或包含C源文件。合并编译的C和ASM文件是链接器的工作,而不是NASM。好的,谢谢。我搞错了。我无法在启动时获得内存初始化,所以它给我的错误是“缺少操作系统”。因为我不能将ORG关键字与ELF一起使用,所以我无法初始化内存,所以我尝试了问题编辑部分给出的内存初始化替代代码。您的问题不是内存初始化。你完全错了。有大量非常重要的代码您还没有编写,并且您生成的可执行文件不是有效的引导加载程序。在继续之前,请通读有关x86“裸机”编程的教程。是否有其他方法在汇编文件(*.asm)中包含C函数?您似乎感到困惑。NASM不是C编译器。它不能编译或包含C源文件。合并编译的C和ASM文件是链接器的工作,而不是NASM。好的,谢谢。我搞错了。我无法在启动时获得内存初始化,所以它给我的错误是“缺少操作系统”。因为我不能将ORG关键字与ELF一起使用,所以我无法初始化内存,所以我尝试了问题编辑部分给出的内存初始化替代代码。您的问题不是内存初始化。你完全错了。有大量非常重要的代码您还没有编写,并且您生成的可执行文件不是有效的引导加载程序。在继续之前,请通读有关x86“裸机”编程的教程。
        [Bits 16]
        extern bootmain
        start:
        mov ax, 07C0h ; Set up 4K stack space after this bootloader
        add ax, 288 ; (4096 + 512) / 16 bytes per paragraph
        mov ss, ax
        mov sp, 4096
       call bootmain
       mov ax, 07C0h ; Set data segment to where we're loaded
       mov ds, ax
       times 510-($-$$) db 0; Pad remainder of boot sector with 0s
       dw 0xAA55 ; The standard PC boot signature