• 締切済み

VC++2010expressのアセンブラについて

toshiyukの回答

  • toshiyuk
  • ベストアンサー率41% (36/87)
回答No.2

それほど詳しいわけではないですが 最適化されて使われてないとか、 逆アセンブルのコードを見ると分かるかも知れません。

7777777v
質問者

補足

わかりました、デバグを活用するのですね。 回答ありがとうございました。

関連するQ&A

  • 配列変数のポインターが勝手に変わる

    下記の2個のファイルを持つプログラムでインラインアセンブラのcall命令で配列変数のポインター(アドレス)が勝手に変わる現象をおしえてください。 但し、配列の最初のポインターのみが変わる。 開発環境はWin7(64bit)、VC++2010無償版です。 main.cpp int *disp; int data[3]; WinMain() { _asm mov disp,offset disp_top ・ ・ ・ メッセージループへ _asm{ disp_top://下記move()からcallされた時 lea eax,data//下記のmove()関数のeaxの値より16番地少ない lea ebx,data+4//下記のmove()関数のebxの値と同じ lea ecx,data+8//下記のmove()関数のecxの値と同じ ・ ・ ・ ret   } } move.cpp extern int *disp; extern int data[3]; void move() { _asm{ lea eax,data lea ebx,data+4 lea ecx,data+8 call disp   } }

  • 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 } }

  • VC2008のアセンブラ出力

    Visual C++ 2008 Express Editionで勉強をしています。 Cで簡単なプログラムを作り、そのアセンブラ出力を見ているのですが、下のアセンブラリストの###部のようなCの記述と関係ないコードが追加されます。この行を削除してアセンブルしても動作に問題ないように見えます。 このコードが追加される意味を教えて下さい。名前からセキュリティに関係しそうですが…… またプログラムによって追加される場合と、されない場合があります。何故でしょう? ご教示いただければ幸いです。 ----scanf.c #include <stdio.h> #include <stdlib.h> int main(void) { int i; char buf[256]; scanf("%s",buf); i = atoi(buf); printf("%d\n",i); return 0; } ----- -----scanf.asm ; Listing generated by Microsoft (R) Optimizing Compiler Version 15.00.30729.01 TITLE D:\vc_asm\scanf.c .686P .XMM include listing.inc .model flat INCLUDELIB LIBCMT INCLUDELIB OLDNAMES _DATA SEGMENT $SG3702 DB '%s', 00H ORG $+1 $SG3703 DB '%d', 0aH, 00H _DATA ENDS PUBLIC __$ArrayPad$ PUBLIC _main EXTRN _printf:PROC EXTRN _atoi:PROC EXTRN _scanf:PROC EXTRN ___security_cookie:DWORD EXTRN @__security_check_cookie@4:PROC ; Function compile flags: /Odtp _TEXT SEGMENT _buf$ = -264 ; size = 256 __$ArrayPad$ = -8 ; size = 4 _i$ = -4 ; size = 4 _main PROC ; Line 5 push ebp mov ebp, esp sub esp, 264; 00000108H mov eax, DWORD PTR ___security_cookie ###この行 xor eax, ebp ###この行 mov DWORD PTR __$ArrayPad$[ebp], eax ###この行 ; Line 8 lea eax, DWORD PTR _buf$[ebp]  (中略  Cで記述した内容の動作が記載) ; Line 11 xor eax, eax ; Line 12 mov ecx, DWORD PTR __$ArrayPad$[ebp] ###この行 xor ecx, ebp ###この行 call @__security_check_cookie@4 ###この行 mov esp, ebp pop ebp ret 0 _main ENDP _TEXT ENDS END -----

  • アセンブラでコマンドライン引数を取得する方法

    50歳からアセンブラプログラムを趣味で勉強しております。 一つ壁に当たりました。 コマンドライン引数が何処にあるのかわかりません。 Windows7で nasm -fwin32 test.asm alink -oPE -subsys console test.obj crtdll.lib -entry start アセンブル、リンクしています。 test.asm extern printf section .text global _start _start: push ebp mov ebp,esp mov eax,[ebp+8] push eax mov eax,A101 push eax call printf add esp,8 pop ebp ret section .data A101: db 'argc = %d', 10, 0 で、argc = 2147340288 と表示されます。 どうぞよろしくお願いいたします。

  • CからC++の関数呼び出し

    CからC++の関数を呼び出して値を取得したいのですが、コンパイルエラーになってしまいます。 呼び出す関数内でさらに同じクラスの関数を呼び出して値をreturnしたいだけなのですが、 ご教示願います。 ソースは下記のような感じです。 Cソース(AAA.c) main(){ ・・・・・ if ( funcA() ){ ・・・・ } } C++ソース(BBB.cpp) int clsB::funcB { return iflg; } extern "C" { int funcA() { return funcB(); } } ※上記externは特に何かの関数内に書いているわけではありません。 C++ヘッダ(BBB.hpp) class clsB : public XXX { private: int iflg; ・・・・ public: int funcB(); ・・・・ } 上記にコンパイルすると、 externしている箇所でfuncBはスコープにありません?のようなエラーが出てしまいます。 ラッパ関数を使って使用するなどと聞いたのですが、やり方がいまいちわかりません。 どうか教えていただけますでしょうか。 また、他にやり方があるかと思いますが、いいやり方があれば教えていただけると幸いです。 以上です、よろしくお願いいたします。 不足内容あれば指定願います。

  • 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言語で書かれたプログラムの中に、アセンブラで書かれた関数を使うため、インラインアセンブラで関数を作っていたのですが、私の能力の限界を感じたので、是非、ご教授願います。以下に示します。 元のアセンブラの関数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"でエラーが出ます内容は構文が間違っているという内容のものです。なお、関数の名前は、意図的に変えてあります。オリジナルとは違います。 大した関数ではないのかもしれないのですが、わからないのでよろしくおねがいいたします。

  • アセンブラの読み方

    お世話になります。 アセンブラを勉強しています。 下記について教えていただけないでしょうか。 よろしくお願いいたします。 1 .file 2 .data 3 var: .long 0x1234 4.text 5 .global main 6 main: 7 movb $1, %al // 値1をレジスタalに代入 8 push %eax // レジスタeaxの内容をスタックに格納 9 call IncReg // 関数呼び出し 10 pop %eax // スタックからレジスタeaxに引き出し 11 push var // 変数varの内容をスタックに格納 12 call IncReg // 関数呼び出し 13 pop %ecx // スタックからレジスタecxに引き出し 14 ret // リターン 15 IncReg: 16 movl %esp, %ebp // pushによって動いたスタックの先頭アドレスをレジスタ ebp に代入 17 movl 4(%ebp), %edx // mainから渡された eax(var) の値をレジスタ edx に代入 18 incw %edx // レジスタ edx の値を2増やす 19 movl %edx, 4(%ebp) // 2増やしたものを引数のあるスタックの場所に代入 20 ret // リターン (質問) 7 でレジスタ al に 1 を代入したのは何か意味があるのでしょうか。 17 の4(%ebp)はスタックポインタの1つ下、つまりmainから渡された引数でよろしいでしょうか。 18 の incw %edx はレジスタ edx の値を 2 増やすという意味でよろしいでしょうか。 13 でレジスタ ecx の値は 1236 になるので正しいでしょうか。

  • 多くのファイルで共通で使う数(C++)

    現在大学の卒業研究でこんな感じのプログラムをC++で作っているのですが ちょっと行き詰っています。 動くには動くのですが、汚いというか。 main.cpp --->実験プログラムのメイン。実験の初期値などが書いてある。 basic.cpp --->基本的な算術計算につかう関数やデータ構造のクラスが書いてある。 sampling.cpp learning.cpp --->実験にいろいろ使うメソッドが書いてある。 これらに加えてbasic.h, sampling.h, learning.hがあり それぞれのcppファイルにインクルードしてあります。 また各cppファイルに共通で使う定数があるのです。たとえば const int DIMENSION = 3; //3というのはたとえばで実験の条件による違う const int ROOP = 20000; などという感じです。これをmain.cppの先頭で宣言して condition.hにextern const int DIMENSION;などと書いて 各cppファイルにこれまたインクルードさせてあります。 今のところこれはこれでプログラムは問題なく動いているのですが 今になって仕様を少し変更する必要が出てきました。 たとえばこのcppファイル群をzikkouという実行ファイルに コンパイルしていたとすると、実行の際に $ zikkou 4 20000 という感じに引数としてDIMENSION,ROOPの値を指定したいのです。 ($はプロンプト画面、ターミナル画面ということです) constのままだとこのように実行の毎にDIMENSION,ROOPを変更するというのは出来ないと思うんですが constを外すと、実行中の安全性が疑問です。 (これらの定数は一回ある値でプログラムが動き出したら絶対に 変わりませんし変わってはいけません) なにか良い方法はございませんでしょうか? よろしくお願いいたします。 なにか情報不足がありましたらおっしゃってください。 すぐに補足いたします(ソースのupは長すぎて難しいです)。 よろしくお願いいたします。

  • 分割コンパイルについて

    現在分割コンパイルが分からずに苦戦しています。 下記のリストは構造体を使わなければコンパイラを通すことができましたが、 使うとなぜか通りません。 あれこれ試しましたがどうしても分かりません。 何がおかしいのでしょうか? *define.hで全てのファイルへの定義や宣言を行わせています。 ////////////// //Main.cpp ////////////// #include <stdio.h> #include <conio.h> #include "define.h" int main( void ){ Tmp[0].c = 15; printf("a: %d\n", a); printf("b: %d\n", b); printf("c: %d\n", Tmp[0].c); printf("NUM:%d\n", NUM); aaa(); bbb(); getch(); return 0; } ////////////////// // A.cpp ///////////////// #include <stdio.h> #include "define.h" void aaa( void ){ printf("a: %d\n", a); printf("b: %d\n", b); printf("c: %d\n", Tmp[0].c); printf("NUM:%d\n", NUM); } ////////////////// // B.cpp ///////////////// #include <stdio.h> #include "define.h" void bbb( void ){ printf("a: %d\n", a); printf("b: %d\n", b); printf("c: %d\n", Tmp[0].c); printf("NUM:%d\n", NUM); } ////////////////// // define.cpp ///////////////// #include "define.h" int a = 10; int b = 20; struct Parameter { int c; }; struct Parameter Tmp[NUM]; ////////////////// // define.h ///////////////// #define NUM 100 extern int a; extern int b; extern struct Parameter Tmp[NUM]; void aaa( void ); void bbb( void );