1

C言語とアセンブリコードを含む混合コードを使用して、ブートローダーで簡単な電卓アプリケーションを作成しています。

私の 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 ファイルを使用し、Disk Explorer を使用してこの add_asm ファイルを配置することで、USB ドライブを起動可能にします。しかし、起動時に次のメッセージが表示されます:Missing Operating Systemこれは、アセンブリファイルで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

しかし、それも機能しません...起動時に「Missing Operating System」と同じエラーが表示されます。

アセンブリ ファイル (*.asm) に C 関数を含める別の方法はありますか? 私はここで立ち往生しています。何か提案があれば教えてください。ありがとうございました。

4

1 に答える 1

1

通常の C プログラムをそのようなブートローダーに変えることはできません。

  • ブートローダーが実行される環境は、通常の実行可能ファイルとは大きく異なります。特に、リンクできる C ライブラリ (または、さらに言えば、リンカーはまったくありません!) が含まれていないため、適切なバージョンでリンクしない限りprintf()、およびのような関数scanf()は使用できません。

  • プログラムを 32 ビット実行可能ファイルとしてコンパイルしています。x86 システムは 16 ビット モードで起動します。そのモードに切り替えるにはかなりの量の初期化が必要ですが、ここではそのどれもありません。

  • プログラムを Linux ELF (あるいは Windows PE?) 実行可能ファイルとしてコンパイルしています。これは、ブートローダーの正しい形式ではありません。

于 2013-05-25T16:51:29.877 に答える