Visual Studioを使用したWindows用アセンブラー

私たちの多くは大学でアセンブラーを勉強しましたが、ほとんどの場合これは単純なDOSアルゴリズムに限定されていました。 Windows用のプログラムを開発する場合、アセンブラー用のコードを作成する必要がある場合があります。この記事では、Visual Studio 2005用のプログラムでアセンブラーを使用する方法を説明します。



画像



プロジェクト作成



この記事では、C ++コードからアセンブラーを呼び出し、その逆を行い、データを転送し、Visual Studio 2005に組み込まれたデバッガーを使用してアセンブラーコードをデバッグする方法について説明します。



まず、プロジェクトを作成する必要があります。 Visual Studioをオンにして、[ファイル]> [新規]> [プロジェクト]を選択します。 Visual Studioでは、プロジェクトタイプ選択ウィンドウにアセンブラー言語がないため、C ++ Win32プロジェクトを作成します。 新しいプロジェクトの設定ウィンドウで、「空のプロジェクト」を選択します。



画像



デフォルトでは、Visual Studioはアセンブラーコードを含むファイルを認識しません。 アセンブラサポートを有効にするには、* .asmファイルをコンパイルする必要があるプログラムを示すことにより、プロジェクトのアセンブリ条件を構成する必要があります。 これを行うには、メニュー項目「Custom Build Rules ...」を選択します。



画像



開いたウィンドウで、さまざまなファイルの特別なコンパイルルールを指定できます。VisualStudio 2005には* .asmファイルの既製のルールが既にあります。「Microsoft Macro Assembler」ルールをチェックすることで有効にするだけです。



画像



ソースコードを追加する



プロジェクトのソースコードの記述に移りましょう。 C ++でソースコードを追加することから始めましょう。 Source Filesフォルダーに新しいファイルを追加します。 テンプレートとして、C ++ファイルを選択し、目的のファイル名を入力します(例:main.cpp)。 ユーザーが入力した名前を読み取る関数を作成し、読み取り名へのリンクを返すreadName()関数の形式でこれを書き込みます。 ファイルのおよそ次の内容を取得します。



  #include <stdio.h>
 
 void main()
 {
     printf( "こんにちは、あなたの名前は何ですか?\ n");
 }

 void * readName()
 {
    文字名[255];        
     scanf( "%s"、&name);
    リターン&名前;
 } 




ユーザー名がわかったので、あいさつを印刷できます。このメッセージは、アセンブラーで記述するsayHello()関数によって表示されます。この関数を使用するには、別のファイルで定義されることを最初に示す必要があります。このため、main.cppにブロックを追加します。



  extern "C"
 {
     void sayHello();
 } 




このブロックは、sayHello()関数が別のファイルで宣言され、C呼び出し規則を持つことをコンパイラーに伝えます。 C ++コンパイラーは関数名を歪曲するため、呼び出し規則は必須です。 さらに、sayHello()関数のreadName()関数を使用します。このため、readName()関数を定義する前にextern“ C”を追加する必要があります。これにより、“ C”呼び出し規則を使用して他のファイルからこの関数を呼び出すことができます



コードをアセンブラーに追加します。このため、ソースフォルダーに新しいファイルを追加します。 タイプテキストファイル(.txt)を選択し、名前フィールドで.txtを.asmに置き換えます。ファイルhello.asmを呼び出しましょう。 sayHello()関数を宣言し、使用する外部関数を指定します。 次のコードを取得します。



  .686
 .MODEL FLAT、C
 .STACK

 .DATA
     helloFormat BYTE "Hello%s!"、10.13.0
    
 .CODE
 readName PROTO C
 printf PROTO arg1:Ptr Byte、printlist:VARARG
 sayHello PROC
     readNameを呼び出す
     printf、ADDR helloFormat、eaxを呼び出す
     ret
 sayHello ENDP
終了 




これでプロジェクトを開始できます。これを行うには、[デバッグ]> [デバッグなしで開始]を選択するか、Ctrl-F5を押します。 すべてが正しく完了すると、プログラムウィンドウが表示されます。



画像



タスクを少し複雑にしましょう。パラメーターを受け取って値を返すアセンブラー関数を作成してみましょう。 例として、整数を受け入れてその桁の合計を返すcalcSumm()関数を作成します。 calcSumm関数に関する情報を追加し、数値を入力して実際に関数を呼び出すことにより、C ++コードを変更しましょう。 hello.asmファイルに関数を追加すると、戻り値はeaxに配置され、パラメーターはPROCキーワードの後に​​宣言されます。 すべてのパラメータはプロシージャコードで使用でき、スタックから自動的にポップされます。 プロシージャでローカル変数を使用することもできます。 これらの変数を手順の外部で使用することはできません。 これらはスタックに保存され、プロシージャから戻るときに削除されます。



  .686              
 .MODEL FLAT、C
 .STACK
 .DATA
     helloFormat BYTE "Hello%s!"、10.13.0
	
 .CODE
 readName PROTO C
 printf PROTO arg1:Ptr Byte、printlist:VARARG

 sayHello PROC	
     readNameを呼び出す			
     printf、ADDR helloFormat、eaxを呼び出す
     ret	
 sayHello ENDP 

 calcSumm PROC a:DWORD	
     xor esi、esi
     mov eax、a
     mov bx、10
 @div:
     xor edx、edx
     div bx
     ESI、EDXを追加	
     cmp x、0
     jne @div
     mov eax、esi
     ret
 calcSumm ENDP

終了 




プロジェクトを実行すると、次の実行結果が表示されます。



画像



デバッグ



もちろん、このタスクに複雑なことはなく、アセンブラーを使用する必要はまったくありません。 Visual Studioがアセンブリ言語開発のために提供するものを検討することは、より興味深いでしょう。 デバッグモードを有効にして、hello.asmにブレークポイントを設定して、プロジェクトを実行してみましょう。次のように表示されます。



画像



[逆アセンブリ]ウィンドウ([デバッグ]> [ウィンドウ]> [逆アセンブリ])には、このオブジェクトファイルのアセンブラコマンドが表示されます。 C ++で記述したコードは黒で示されています。 逆アセンブルされたコードは、対応するC ++ /アセンブラコードの後に​​グレー表示されます。 [逆アセンブリ]ウィンドウを使用すると、コードをデバッグしてステップ実行を実装できます。



レジスタウィンドウ([デバッグ]> [ウィンドウ]> [レジスタ])では、レジスタの値を表示できます。



メモリウィンドウ([デバッグ]> [ウィンドウ]> [メモリ])を使用すると、メモリダンプを確認できます。左側に16進アドレスが表示され、右側に対応するメモリセルの16進値が表示されます。ウィンドウ上部の対応するフィールドにアドレスを入力してナビゲートできます



All Articles