理論的には、DJGPP (DOS 用の gcc ポート) でコンパイルされたプログラムのみが、DOS または Windows (XP 以下、通常は Vista/7/8 ではない) で実行する場合に、DOS エクステンダーを介して DOS サービス機能を合法的に使用できます。また、gcc は 16 ビットの x86 コードを生成しません。
さらに、インラインアセンブリを実際に学ぶ必要があります(グーグルで調べてください)。
コードが次のようになる場合のコンパイル可能なバージョン:
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
asm(".section .data");
asm("hello: .string\"Hello, World!$\"\n");
asm(".section .text");
asm("movb $0x09, %ah\n"); // movl->movb
asm("movl $hello, %edx\n"); // mov->movl,hello->$hello,dx->edx
asm("int $0x21"); // 0x21->$0x21
system("PAUSE");
return 0;
}
ただし、次の理由から、インライン アセンブリとして適切である可能性は低いです。
- あなたのコードはレジスタを破棄し、どれが破棄されたかをコンパイラに通知しないため、プログラムの状態が破損し、クラッシュやハングにつながる可能性があります。
- 個々の asm ステートメントに命令を記述します。その間に、コンパイラはあらゆる種類のコードを挿入し、インライン アセンブリを中断できます。それを防ぐために、関連する命令を単一のブロックに入れたいと本当に思っています。
このようなものが良いでしょう:
asm volatile (
".section .data\n"
"hello: .string \"Hello, World!$\"\n"
".section .text\n"
"movb $0x09, %ah\n"
"movl $hello, %edx\n"
"int $0x21\n"
);
残念ながら、これは DJGPP でも機能しません。この問題は、DJGPP と DPMI ホスト (CWSDPMI) によって行われるメモリ セグメンテーション セットアップ (おそらく仮想メモリ) と関係があります。何が間違っているのか正確にはわかりませんが、上記のコードはそのままでは機能しません。
そのため、プログラムをコンパイルする OS を特定し、その OS に適したインライン アセンブリ コードを記述してください。つまり、正しいレジスタとシステム コール メカニズムを使用してください。
DOS int 21h 関数は、ネイティブの Windows および Linux アプリでは機能しません。限目。間違ったチュートリアルを持っています。