【问题标题】:Bootloader using mixed code using EXTERN使用 EXTERN 混合代码的引导加载程序
【发布时间】:2013-05-25 16:31:20
【问题描述】:

我正在使用混合代码(包括 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)是:

 [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 驱动器可启动。 但是在启动时它显示消息:缺少操作系统 那么这是在程序集文件中不使用 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 函数吗? 我被困在这里。如果有什么建议请给我。 谢谢。

【问题讨论】:

    标签: c assembly nasm boot


    【解决方案1】:

    你不能像那样把一个普通的 C 程序变成一个引导加载程序。

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

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

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

    【讨论】:

    • 还有其他方法可以在汇编文件 (*.asm) 中包含 C 函数吗?
    • 你似乎很困惑。 NASM 不是 C 编译器。它不能编译或包含 C 源文件。合并编译的 C 和 ASM 文件是链接器的工作,而不是 NASM。
    • 好的,谢谢。我弄错了。我无法在启动时进行内存初始化,所以它给了我“缺少操作系统”的错误。由于我不能将 ORG 关键字与 ELF 一起使用,因此我无法初始化内存,因此我尝试了在问题的编辑部分中给出的内存初始化替代代码。
    • 你的问题不是内存初始化。 您的做法完全错误。 有大量非常重要的代码您没有编写,而且您生成的可执行文件不是有效的引导加载程序。在继续之前,请通读有关 x86“裸机”编程的教程。
    猜你喜欢
    • 1970-01-01
    • 2012-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-29
    • 2019-11-18
    • 2014-12-19
    • 2010-11-20
    相关资源
    最近更新 更多