• ベストアンサー

__asm mov eax,100とは?

他人のC言語ソースコードの中に #define BugFix __asm mov eax,100 というマクロがありました。 主に以下のように関数の終わりのほうに記述されているのですがどんな意味があるのか教えてください。 void func() {     /*何か処理*/     BugFix } よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • petertalk
  • ベストアンサー率69% (156/225)
回答No.1

c/c++では、インラインでアセンブラ言語の記述もできます。 これはそのインラインアセンブラの記述です。 インラインでアセンブラ言語を記述するためには、アセンブラ言語そのものの意味に加えて、 アセンブラが呼び出された時に、渡されるレジスタの内容や、c/c++上の変数の参照の方法、 変更していいレジスタ、いけないレジスタ等、 いくつかのルールがあり、知っておく必要があります。 その中で、関数の戻り値は、eaxレジスタの内容が使われる、というルールがあります。 ご質問の __asm mov eax,100 は、eaxレジスタを100にセットしているので、 このまま関数から抜けると、func() は 100 という戻り値を返したことになります。 推測ですが、func() は void で定義されているので、return で値を返すことはできないし、 間違って、呼び出し元が func() からの戻り値を参照しても、不定になってしまいます。 本来であれば、int func() に変更して return 100 とするとか、 呼び出し元で viod func() とに変更するのが正しい修正なのですが、 なるべく大きな修正にならないように、強制的に戻り値を 100 に固定する目的で、 このようなマクロを挿入しているように思います。

すると、全ての回答が全文表示されます。

関連するQ&A

  • extern指定子と実装(#include)について

    2点質問があります。 #1.#includeできるのはヘッダーファイルのみなのでしょうか。    ヘッダファイルをインクルードしなくてはいけないのは、わかっ   てます。.c(Cソースコード)はインクルードできないのでしょう   か。 #2.#1と絡んだことについてです。    たとえば、2つの関数Func1()とFunc2()とをメインルーチンと   は別のソースコードに関数の処理を記述したとします。    ファイル名:Func.c    中身:Func1とFunc2の処理内容    次にこれをメインルーチン内で使用するために以下のように記述   して保存したとします。    ファイル名:Func.h    中身:#include "Func.c" extern void Func1(void); extern void Func2(void); 最終的に、ファイル名:main.c         #include "Func.h" --------------- Func1(); Func2(); というようなことは可能でしょうか。

  • 複数ファイルに分割した時の構成について

    大学の卒論にむけてプログラムを書いていて、一つのmain.cでは長くなってきたので、関数を func1.h func1.c のような別ファイルに記述することにしました。 その現在の構成を、質問欄の下部に簡単に書いたので、構成が自然かどうか意見をお聞きしたいです。特に、 「include文、define文をヘッダファイルにまとめて、各ファイルからincludeしている構造」がコードの記述方法として、きもちわるくないか、一般的かどうか、教えてください。 このようにした理由は、 ・defineマクロを多くのサブ関数で利用している。 ・define定義の値を細かく変えながら実行し、結果の違いを出力したい。 ・その為、各ファイルの頭にdefine定義を置いた場合、定義の値を  いちいち全てのファイルで変更しなければならなくなり、面倒…。 →defineマクロをdefine.hにまとめた。ついでに、<stdio.h>,<math.h>なども置いてしまえばスッキリするかも~。 という経緯です。 理学の学科でまわりに詳しい人がいなく、 プログラム知識もほぼ独学なので、不安に感じて質問しました。 よろしくおねがいします。 +++++++++++++ 以下が、簡単なファイル構成です +++++++++++++ -----define.h----- #include <stdio.h> #include <math.h> #define A_MAX 3 #define B_MAX 5 -----main.c---- #include "define.h" int main() { func1(); func2(); func3(); } -----func1.h---- #include "define.h" void func1(int hoge); //プロトタイプ宣言 -----func1.c---- #include "func1.h" void func1() { hogehoge; } ------func2以下、func1と同構造

  • インラインアセンブラの関数について質問です。

    C言語で書かれたプログラムの中に、アセンブラで書かれた関数を使うため、インラインアセンブラで関数を作っていたのですが、私の能力の限界を感じたので、是非、ご教授願います。以下に示します。 元のアセンブラの関数write_mem82(int addr, int data) MOV EAX, [ESP+4] MOV AL, [ESP+8] MOV [EAX], AL RET です。これは、OS○作○門という本に載っていたものですが、プログラムをインラインアセンブラにすると、成功するのかふと疑問に思ったのです。よって、アセンブラの種類は、nasmを基にしたnaskです。 こういうことは、その本のサポートページか何かで質問すればよい的なことをおっしゃる方もおられると思います。残念ながら、サポートページは、ほぼ凍結状態で、何年待てば回答が返ってくるのか?という状態です。 そういう経歴で、ここの質問させていただくに至りました。 肝心の、私が書いてコンパイルエラーになるプログラムを書きます。 static __inline__ void write_mem82(int addr, int data){ __asm__ ( "MOV EAX,[ESP+4]": "MOV AL,[ESP+8]" "MOV [EAX],AL" "RET" ); } です。"MOV [EAX],AL"でエラーが出ます内容は構文が間違っているという内容のものです。なお、関数の名前は、意図的に変えてあります。オリジナルとは違います。 大した関数ではないのかもしれないのですが、わからないのでよろしくおねがいいたします。

  • C++とインラインアセンブラでのポインタ値が違う

    C言語で取得した配列変数の先頭ポインターとインラインアセンブラで取得したポインターが異なる現象が起きました。 2個のソースファイルを持つ下記プログラムで、pointer1とpointer2が異なる原因を教えてください。 ただし、提示のソースはあくまで、見本で実際には多くの変数やコードを記述しています。 開発環境はWin7(64bit)、VC++2010無償版です。 main.cpp #include <windows.h> int *disp; int *pointer1; int *pointer2; int data[8]; void disp_sub(); int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow) { _asm{ mov disp,offset disp_top call disp_sub jmp pgm_end disp_top: lea eax,data mov pointer1,eax } pointer2=&data[0]; if(pointer1 != pointer2)Beep(3000,1000); _asm ret pgm_end: return 0; } sub.cpp extern int *disp; void disp_sub() { _asm{ call disp } }

  • c言語のワーニングを無くしたい

    c言語のダブルポインタ(char **)の引数渡しで困っています。 ワーニングが取れず、無視して実行するとセグメンテーション違反 となります。 ワーニングを取る方法をご存じないでしょうか? もしくは言語仕様、gcc仕様が要因でしょうか? バージョンはgcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-44)です。 001 void func(char **p1) 002 { 003 static char *s="AAA"; 004 **p1 = s; 005 } 006 int main(void) 007 { 008 char *q1; 009 func(&q1); 010 return(0); 011 } $ cc -Wall -o pp pp.c pp.c: In function ‘func’: pp.c:5: 警告: assignment makes integer from pointer without a cast 実行すると004行目で 'セグメンテーション違反です (core dumped)'となります。 004行目を *p1 = s; にするとワーニング無しとなり、 問題無くcall側のq1に先頭アドレスがセットされますが、 何か納得がいきません。 ちなみに、最初のcore吐きプログラムのアセンブルリストは 以下のようになります。 (*)位置で変なコードとなっていまが、ワーニングが出て いるので当然なのかもしれません。 (gdb) disass Dump of assembler code for function func: 0x08048354 <func+0>: push %ebp 0x08048355 <func+1>: mov %esp,%ebp 0x08048357 <func+3>: mov 0x8(%ebp),%eax 0x0804835a <func+6>: mov (%eax),%edx 0x0804835c <func+8>: mov 0x8049560,%eax *0x08048361 <func+13>: mov %al,(%edx) 0x08048363 <func+15>: pop %ebp 0x08048364 <func+16>: ret End of assembler dump. そして 004行目を *p1 = s;にした場合が以下となります。 想定通りのコードですが、何故なのかわかりません。 Dump of assembler code for function func: 0x08048354 <func+0>: push %ebp 0x08048355 <func+1>: mov %esp,%ebp 0x08048357 <func+3>: mov 0x8049560,%edx 0x0804835d <func+9>: mov 0x8(%ebp),%eax 0x08048360 <func+12>: mov %edx,(%eax) 0x08048362 <func+14>: pop %ebp 0x08048363 <func+15>: ret End of assembler dump.

  • HIPOについて質問です

    HIPOには入力・処理・出力とありますが、入力のないHIPOはあるのでしょうか?また、以下のmain()関数、func1()関数をHIPOで記述すると、どのようになりますか? void main(void) { func1(); } void func1(void) { printf("test"); }

  • OpenGLで登録したコールバック関数の引数

    OpenGLで画面を描画をする際に, 以下のソースのように,glutDisplayFuncに関数を登録しています. main関数で,定義した定数や,そのポインタを display_funcに渡したいと思うのですが, どのような方法があるのでしょうか? 現在,私は,グローバル変数を定義して,それをmain関数とdisplay関数で いじっています. ソースコードの整理,関数化のため,できれば,ポインタや引数を渡したいです. どうぞよろしくお願いします. --------------------------------------------- #include <GL/glut.h> void display_func(void) { 描画内容を記述 } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutCreateWindow(argv[0]); glutDisplayFunc(display_func); glutMainLoop(); return 0; } ---------------------------------------------

  • C/C++のインラインアセンブラに関する質問

    使っているコンパイラはボーランドのフリーのC++のコンパイラなのですが インラインアセンブラのソースをコンパイルするとこんなエラーメッセージがでます( 警告 W8002 roger.cpp:8アセンブラを使う為コンパイラを再起動した(関数(main()) エラーE2133 ’tamsm32.exe'を実行できない とエラーメッセージが出ます 調べても解決方法がわからないのですが 解る方は教えてください ついでにコンパイルしようとしたソースは↓です #include<iostream.h> void main(){ int w=8; int w2=5; _asm{ mov eax,w mov edx,w2 }; cout<<w<<endl; };

  • C言語での関数の引数の受け渡しについて

    C言語での関数の引数の受け渡しについて教えてもらいたいのです。 char *p=Goo;  というポインタpがmain関数で定義され、このポインタpをある関数 void func(・・・) に渡すことは出来ますか? つまりポインタを実引数として扱うことはできるのかという事ですが・・・ int p=10; とかだったら、 void func(int test) の関数には、main関数で func(p) で仮引数testにわたせると思うんですが・・・ もし出来るようでしたら、関数の渡し方と定義の記述を教えてください。 どうか宜しくお願いします。

  • x64移行でのインラインアセンブラ修正

    Win32のプログラムをx64に移行する仕事を頼まれました。 プラットフォームをx64に移してビルドを行ったところ、 インラインアセンブラを使用していた以下のコードでエラーが発生しました。 ~前略~ __asm { mov eax, 0; /* EAXに0を入れる */ cpuid; /* CPUID実行 */ mov dword ptr [vender_sig + 0], ebx; /* 最初の4文字 */ mov dword ptr [vender_sig + 4], edx; /* 次の4文字 */ mov dword ptr [vender_sig + 8], ecx; /* 最後の4文字 */ mov byte ptr [vender_sig + 12], 0; /* ラストに \0 */ } ~中略~ __asm { mov eax, 1; /* EAXに1を入れる */ cpuid; /* CPUID実行 */ mov dword ptr [prosessor_sig], eax; /* プロセッサシグネチャ */ mov dword ptr [function_flag], ebx; /* ファンクションフラグ */ mov dword ptr [feature_flag2], ecx; /* Featureフラグ */ mov dword ptr [feature_flag1], edx; /* Featureフラグ */ } ~中略~ __asm { mov eax, 1; cpuid; /* CPUID実行 */ mov dword ptr [t], eax; /* top */ mov eax, 3; cpuid; /* CPUID実行 */ mov dword ptr [m], edx; /* middle */ mov dword ptr [b], ecx; /* bottom */ } ~後略~ x64ではインラインアセンブラが使用できないということはわかったのですが、 これをどう直していいかがわかりません。 アドバイスよろしくお願い致します。

このQ&Aのポイント
  • G6030のインク注入が遅いと感じている方へ。純正のインクを使用しているにも関わらず、黒インクの注入速度が遅い場合、解決策をご紹介します。
  • G6030でのインク注入が思ったよりも遅くて困っている方への対処法について。上から刺すだけの方法ではなかなかインクが注入されない場合、試してみるべきポイントをまとめました。
  • キヤノン製品のG6030で黒インクの注入が遅いという悩みを抱えている方へのアドバイス。純正インクを使用しているにもかかわらず、インクの注入がスムーズに行われない場合の対処法を解説します。
回答を見る

専門家に質問してみよう