使用EXTERN的混合代码的Bootloader

时间:2013-05-25 16:31:20

标签: c assembly nasm boot

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

我的C语言代码是(addasm.c):        #include

      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)是:

 [BITS 16]   ; 16 bit code generation
 [ORG 0x7C00]    ; ORGin location is 7C00
 extern bootmain

  ;Main program
  main:      ; Main program label

  call bootmain

  ; End matter
   times 510-($-$$) db 0    ; Fill the rest of the sector with zeros
   dw 0xAA55        ; Boot signature

现在我正在编译这个

    nasm -f elf -o main.o ccode.asm  #assemble our asm file

但它给了我ORG关键字的错误,它是未定义的关键字。

如果我将删除此关键字,那么它将为我提供无错输出。

删除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驱动器可启动。 但在启动时它显示消息:缺少操作系统 这是在Assembly文件中不使用ORG的问题。 这主要是我使用NASM的ELF问题。但是对于外部C函数和EXTERN关键字,我需要使用ELF。

ORG的替代代码是:

  [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函数? 我被困在这里。如果有任何建议请给我。 谢谢。

1 个答案:

答案 0 :(得分:1)

你无法将普通的C程序变成这样的引导加载程序。

  • 引导加载程序运行的环境与普通可执行文件明显不同。特别是,它不包含您可以链接的C库(或者,就此而言,根本就是任何链接器!),因此除非您链接,否则printf()scanf()等函数不可用适当的版本,你没有做。

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

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