• ベストアンサー

アセンブラでmain関数から作成すると

アセンブラでmain関数から作成すると 以下gasです。 main: pushl %ebp と%ebpを最初にpushしますが、このebpの値はos側がこの実行ファイルをロードするときにセットするという感じでしょうか?

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

  • ベストアンサー
  • nda23
  • ベストアンサー率54% (777/1415)
回答No.1

パラメータはスタックに入れて渡されます。 スタックのポインタとしてebpレジスタが 使用されるという訳です。このレジスタは 呼び出し元も使うので、関数を出るときは 入ったときの値を保証しなければなりません。 そのため、最初にpush命令で値を退避する のです。 その直ぐ後にmov ebp,espと続くはずです。

vfrtgb
質問者

お礼

ありがとうございました。理解しました

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

関連するQ&A

  • アセンブラの読み方

    お世話になります。 アセンブラを勉強しています。 下記について教えていただけないでしょうか。 よろしくお願いいたします。 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 になるので正しいでしょうか。

  • main関数の戻り値

    C言語のmain関数の戻り値はint型ですよね。 私もそういう決まりだと思って守ってきました。 しかし、「mainが戻り値を返すって、どこに返すの?」ということが、私は理解できていません。 私が調べたところでは、「ホスト実行環境」という言葉がこの問題に関係あるようですが、この言葉の意味はよくわからないですし、似た言葉で「ホスト環境」ということばがあるのですが意味も関係もわかりません。 これらは、OSとは違うと思うんですが、自信はありません。 それでも、ない知識を振り絞っていろいろ考えてみると、次のようなことらしいのですが、正しいでしょうか。 ・OSはプログラムの実行に先立ちホスト実行環境を作る。 ・静的記憶域のオブジェクトを初期化するのはホスト実行環境である。 ・関数が、main関数を呼ぶことは可能である。(以下では、main関数が関数から呼ばれる場合は除く。) ・main関数を呼ぶのは、ホスト実行環境が行なう。 ・main関数の中のreturnによってプログラムが終了するのと、exit関数でプログラムが終了することに違いはない。 ・main関数の戻り値は、ホスト実行環境に返される。 ・returnによってホスト実行環境に返される値は、int型である限りなんでもよい。 ・exitによってホスト実行環境に返される値は、int型である限りなんでもよい。 ・必ずexitで値が返されるならば、main関数の中にreturnはなくてもよい。 main関数からの戻り値をどうしようと構わないんだと思うんですが、皆さんの経験の中で、実例としてこういうふうに使われる、というのは何かないのでしょうか。 (ホスト実行環境に値が返される、といっても無視するのでは意味はないと思うのです。 その値の使用例としては、 0が返ってくると「プログラムは正常終了しました。」と表示するとか、0以外の値が返されると別のプログラムが走るとか、 そういうことだと思うんですが。)

  • アセンブラからCの関数を呼び出すには?

    「OS自作入門」を読んで試しています。 フロッピーのブートセクタに自作のブートプログラムを 書き込み、ブートプログラムから自作のOSを呼び出して実行 しています。自作といっても前述の参考書の物まねですが・・・・。 ここまでは全てアセンブラでプログラムを書いてきました。 NASMを使っています。ずっとアセンブラではきついので C言語で書きたいのです。 まずは自作のOSからCで書いた関数を呼び出して実行したいの です。つまり・・・ OS.ASM + TEST.C→OS.BIN としたいのです。OS.ASMは自作のOSです。TEST.CにはCの関数を 書いておき、OS.ASMから呼び出すようにします。 これらをくっつけてOS.BINというファイルにしたいのです。 どうすればいいでしょうか?  (1) ブートプログラムの中で16ビットモードから32ビットモードに 切り替えており、自分でセグメントを決めてあります。TEST.Cも それにあわせる必要があるかと思いますが、どうすれば? (2) OS.ASMとTEST.Cをどうやってくっつけるのかがわからない。 リンカーとか使うのでしょうか?

  • "main"について

    "main"についての質問です。 今まで私は"main"というのはC言語の予約語の一つだと思い込んでいましたので、"main"は変数名には使えないと思っていました。 ところが以下のようなプログラムを実行してみると問題なくコンパイル出来る上に問題なく実行できました。 int main(void) { int main; main = 300; printf("%d\n", main); return 0; } 確かに入門書などを見直してみると、予約語の中に"main"はありませんでしたし、関数名が変数名として使えないとは書いて無いように思います。 でもなんだかしっくりきません。(^^;) 関数ポインタを使う際などは、変数=関数名(p = myfunction)などと書いたりするので、main関数が格納されているメモリなど変なところを書き換えたりしている可能性があるような気がしたのですが、うまく確認する方法を思いつきませんでした・・・。 ただたんに変数が優先的に処理されているだけというのなら納得するしかないのですが。 どなたか詳しい方がいたら教えてください。よろしくお願いします。

  • mainから渡した文字列を関数内で書き換え

    非常に基礎的な質問で申し訳ないのですが mainから渡した文字列を関数内で書き換えることができません。 int型の整数やchar型一文字はできるのですが。。。 例えば以下のようなソースでmainのABCをDEFに書き換えたいとき どのようにすればいいのでしょうか。 (関数の戻り値で変更という方法以外で) 以下のソースでは値は書き換わりませんでした。 void func(char *str2) { str2 = "DEF"; } int main() { char str1[20] = "ABC" printf("%s", str1); //ABC func(str1); printf("%s", str1); //DEFになるようにしたい }

  • 関数の使い方が分りません

    あらかじめ人数がわかっている集団で、科目A、科目B、科目Cの点数を入力後、各々の平均を求めるプログラムを作成したいです。人数も最初に入力してもらいます。 実行例は以下の通りです 人数? 3 科目Aの成績 1人目の点数: 50 2人目の点数: 40 3人目の点数: 90 ・ ・ ・ 科目Aの平均:60.0 科目Bの平均: 科目Cの平均: この実行例から、 1、人数-ninzuを取り込む 2、main関数の前に平均を求めるためのaverage関数を書く。ninzu分の配列tensu[]を定義し、for文で点数を取り込む。平均を計算し、その値を返す。 と考えました。 main関数の中でninzuを取り込んで、関数averageに飛んでninzu分の配列-tensu[ninzu]をつくったんですが、エラーの嵐です(泣) なんか、根本的に違う気がして本で調べてみたんですが、分りませんでした。 main中で取り込んだninzuを関数の中で使う事は出来ませんか? あとmain中で printf("科目Aの成績\n");をかき、このあとに関数を呼び出せれば実行例どおりに作れると思うんですが、どうやったら関数を呼び出せますか? もう手が付けられないです…。助けてください また、「こうしたら?」みたいなアドバイスもありましたらぜひお願いします! なにぶん超初心者ですので、よろしくお願いします。

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

  • 指定したメモリアドレスの値の読み出し(自己改変コードの作成)

    C言語で、自己改変コードの作成を行っています。 実行時にmain関数の中で、そのコードが含む(main関数ではない)別の関数がロードされているメモリ領域に対して処理を行い、自己改変を実現しようと考えています。 変更を加えたい関数がロードされたメモリ領域を特定し、そのメモリ領域への書き込みをmprotectシステムコールを用いて書き込み可能にするところまではできました。 しかし、その先、そのメモリ領域の内容を読み出し、変更を加えるところがどうもうまくできません。 例えば、あるメモリアドレス0x804845cに格納されている値を読み出したい場合、どのようにしたら良いのでしょうか? さらに、そこに格納されている値を変更したい場合、memsetシステムコールを用いて書き込みを行おうと考えているのですが、正しいでしょうか? (例:メモリアドレス0x804845cに値0x23を格納したい場合 memset((0x804845cへのポインタ), 0x23, 1); のようにする) アドバイスをお願いいたします。

  • PIC mainループについて

    PICマイコン+PICKit3で簡単なプログラムを作成して遊んでいるのですが、 ふと疑問に思ったことがあるので、質問します。 プログラムは2種類の値を用意し、スイッチの入力を見て片方をLCDに表示するといった 簡単なものですが、デバッグ中にmainプログラムの最終行まで実行した後、 再度mainプログラムの頭に戻ったとき、RAMの値がすべてクリアされている ことに気が付きました。 当初の目論見ではRAMの値を使用して表示を切り替えるつもりだったので、少し困りましたが、 方法を変えて完成させました。少し調べてみると、mainプログラムが頭に戻ってきた時、startup.asm のファイルを通り、RAMの値をクリアしていることが分かりました。 そこで質問なのですが、mainプログラムが頭に戻ってくるとRAMの値は必ずクリアされてしまう ものなのでしょうか?そうだとすると、RAMの値を残したい場合はどうすれば良いのでしょうか? ちなみにコンパイラはHITEC PICC-18です。

  • C言語とアセンブラ言語による計算プログラミング

    "AB間の距離を求めなさい。" 下の画像において、AC=r1、BC=r2、∠ACB=α°とするとき、AB間の距離dを求めなさい。 上記の問題について困っております。 この問題の解答については、C言語とアセンブラ言語によるプログラミングで考えるようになっており、FPU(MATH COPROCESSOR)を使用し、C言語側で変数や関数宣言、printfなどでの計算結果出力を記述し、アセンブラ言語側で計算するプログラム問題です。 原則として、C言語側で計算してはいけない仕様になっています。 そして、2つのオブジェクトファイルをリンクさせ、実行可能ファイル(.exe)を作成し、コマンドプロンプト に計算結果を表示する。とういう問題です。 ・アセンブラ言語側での使用する命令のプロセッサアーキテクチャのタイプは「.386」 ・作成するオブジェクトのメモリモデルは、Windowsなので「FLAT」 図の画像は添付してあるので、どうかご回答のほどよろしくお願い致します。