
参照のために行頭に行番号を付けます。
XX:
01: b8 57 61 6b 61 mov $0x616b6157,%eax
02: 53 push %ebx
03: 50 push %eax
04: ba 04 00 00 00 mov $0x4,%edx
05: bb 01 00 00 00 mov $0x1,%ebx
06: b8 04 00 00 00 mov $0x4,%eax
07: 89 e1 mov %esp,%ecx
08: cd 80 int $0x80
09: 58 pop %eax
10: 31 c0 xor %eax,%eax
11: 5b pop %ebx
12: c3 ret
上記を一行ごとに開設すると以下の通りです。
01: 'Waka'の4文字をeaxへ 57='W', 61='a', 6b='k'
02: ebxをスタックへ (元のebxを保存するため)
03: eax(='Waka')をスタックへ
04: edxに4を代入 4は4バイトの意
05: ebxに1を代入 1は標準出力の意
06: eaxに4を代入 4はシステムコール4番(write)
07: esp(スタックポインタ)をecxに代入
08: Intel x86系Linuxでの(レガシー)システムコール
09: スタックの値をeaxに取り出し (03:で入れた値を除去するため)
10: eaxをゼロにする (同じ値のxorは常に0でmovより速いのでxorを使う)
11:スタックの値をebxに取り出し (02:で保存した値を復元するため)
12: 関数から戻る
Cで書けば
write(1,"Waka",4);
の1行で書ける内容をアセンブラで(レガシー)システムコールを使って書いたものですね。
# Cの文字列はヌル終端で"Waka"は5バイトになるので
# 完全には一緒じゃないけど、やりたいことは同じ
呼び出されたシステムコール内ではeaxが4なのでwriteシステムコールとわかり、ebxが1なので標準出力へ、ecxにスタックポインタの先頭すなわち'Waka'のアドレスがあり、edxから4バイト書き込みと分かる。
ここでいう12の解説の関数から戻るというのはどういう意味なのでしょうか?教えて頂けると幸いです。
A 回答 (11件中1~10件)
- 最新から表示
- 回答順に表示
No.11
- 回答日時:
>関数から戻るの「から戻る」とはどこに戻るのかは、
>考えなくても良いと言うか、省略されていると言う事でしょうか?
省略じゃなくて戻り先はスクックに積まれてます。retはそれを見て
飛ぶだけです。
>後、eaxの「0」は、なぜ使えるのでしょうか?
こういうのはコンパイラやOS等で決まっている Calling Convension(呼び出し規約)を学びましょう。Cの関数呼び出しをマシン語でどう表現するかは一通りではありません。
No.10
- 回答日時:
> return 0 を使っているとなぜわかったのでしょうか?
質問文で与えられた情報から、判るはずがない。
No.6 に書いたとおり、単なる憶測だ。
10: xor %eax,%eax で eax にセットしている 0 が
return 0 の 0 なのかどうかを確認するには、
関数 XX() を呼び出してるコードの方で
XX() の返値をどう扱ってるか検証するしか、方法が無い。
return 0; だと書いたのは、ヤマカンだよ。
No.9
- 回答日時:
> そのルーチンは何なのでしょうか?教えて頂けると幸いです。
またまた、何を聞いてるのか判らん質問を...
日本語が苦手なの?
それが、関数 XX を呼び出したのは具体的にプログラム中のどこか?
という質問なら、答えは「知らんがな」。
呼ばれるほうのコードだけを提示して、どこから呼ばれたかを
回答者が知る方法は無い。ええかげんにせえよ。
どうしてもそれが知りたいなら、プログラムの逆アセンブルから
「call XX」の文字列を検索するか、
そのプログラムをデバッカ内で実行して
12: ret に置いたブレークポイントで停まったときに、
スタックの先頭を見るか、1ステップだけステップ実行すれば
戻る先がどこだったかが判る。
それとも、まさか「ルーチン」とは何か? と聞いてるのであれば、
ルーチンとは、 call, ret 無しで実行される一連の命令からなる
プログラムの断片のこと。高級言語の立場からは、それを
関数とか、プロシージャとか、メソッドとか、いろいろに呼ぶけれど、
要するにアセンブリプログラムから見ると、call で入っていって
ret で抜けてくる一連の命令のカタマリのこと。
No.8
- 回答日時:
> 質問の解説の12についてもう少し詳しく教えて頂けると
それを No.2 に書いたんだがな。
12: ret
を
12: 関数から戻る
と説明したということは、
サブルーチン XX を「関数」だと考えているということ。
ここで関数というのは、たぶん、返値を持つサブルーチンという意味で、
No.6 に書いたように、call XX の次に置かれた命令を実行する時点で
eax に入っている値が XX の返値だという規約なのだろう。
「戻る」ために ret が何をやっているのかは、No.2 に書いたとおり。
C っぽく、
int XX(void) {
write(1,"Waka",4);
return 0;
}
と書けば解る?
あと、くどいようだが、
12: ret
で「戻る」行き先は、OS でも、シェルでもなく、
当該のプログラム内でサブルーチン XX を呼び出したルーチン
だからね。
No.7
- 回答日時:
> OSに戻ると言う事はつまりどう言う事でしょうか?教えて頂けると幸いです。
すいません、書き漏れましたが、「OSに戻る」もあくまで一例です。
WindowsのExplorerから起動したプログラムであればExplorerに戻るし、
コマンドプロンプトから実行したプログラムであればコマンドプロンプトに戻ります。
とあるCプログラムから起動した別のプログラムなら、呼び出したCプログラムに戻ります。
そもそも、「戻る」という意味が分からないということですかね?
仕事中に、電話が掛かってきたら、その時やってた仕事を中断して電話に出て話しますよね?電話が終わったら(すぐ来いとかの命令電話でなかったのなら)、さっきまでやってた仕事に戻りますよね?その「戻る」と同じ意味です。
Cプログラムで言うと、
(前略)
f = fopen("filename.txt","r");
if(f) {
(後略)
と書くと、fopen関数が実行されて、そのfopen関数の実行が終わると、このプログラムの次の行であるif(f)が実行されますが、それが「fopen関数が終了する(= fopenプログラム内でreturnが実行されると)と呼び出したプログラムに戻る」という意味です。
No.6
- 回答日時:
> 関数から戻るの「から戻る」とはどこに戻るのかは、
> 考えなくても良いと言うか、省略されていると言う事でしょうか?
ret の機能は、No.2 に書いたとおり。
esp が指すメモリの中身で eip の値を書き換える。
eip が変わるから、次に実行される命令のアドレスが変わる。
どこに戻るのかは、XX の実行が始まった時点で
スタックの一番上に積まれていなければならない。
呼び出し元で call XX を実行して XX: へやって来たのならば、
call を行った時点でスタックはそうなっている。
> eaxの「0」は、なぜ使えるのでしょうか?
何を質問しているのかがよく判らないが...
10: xor %eax,%eax としても良い理由を聞いているのであれば、
呼び出し元(call XX を行った側のコード)で
サブルーチン XX が eax の値を保存することを期待してないからでしょう。
何のために 10: xor %eax,%eax としているのか? を聞いているのなら、
それは、この断片的なコードからは判断する方法がないが、
おそらく XX が eax に返値を入れて返すという規約にしてあるのでしょう。
xor %eax,%eax
ret
で、合わせて retuen 0; をやってるつもりというか。
システムコールの返値を扱わずに XX の返値を 0 に固定しているのは、
たぶん、XX の返値はエラーコードを意味していて、
システムコール4番でエラーが生じることは考えてないからでしょう。
あと、ちょっと気になったんだが、86系なら
mov は mov 移す先,移す元 の順だよね?
01: mov $0x616b6157,%eax は変だと思うのだけれど。
No.5
- 回答日時:
int main() から return 0; すると、
制御は C のスタートアップルーチンに戻る。
OS に戻るには、スタートアップルーチンの中で
それなりのシステムコールを呼び出す必要がある。
No.2
- 回答日時:
86系の32ビットモードですかね。
ret は、スタックトップの内容を命令ポインタへポップする命令です。
あえて変なアセンブリもどきで書けば
mov %eip,[%esp]
add %esp,4
みたいなもの。
プログラムのどこかで
call XX
を行って、このコードへやってきたはずですが、
ret を実行すると、その call の次の命令へ制御が移ります。
「12: 関数から戻る」とありますが、そこは
「ルーチンから戻る」のほうが穏当でしょう。
C の return など、高級言語でいう「関数から戻る」には
ret 以外にもいろいろな処理が必要です。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
vba 正規表現について教えてく...
-
プログラム言語
-
if関数とは?
-
pythonでのローカルファイルか...
-
画像生成AIのプロンプトの作り...
-
pythonについて(初心者です)
-
今のプログラミング言語
-
プログラミングについて
-
自作scratch アニメの商用利用
-
OS入ってる機器のソフト・アプ...
-
CSVファイルの複数行削除
-
パイソンのソースコードをChatG...
-
プログラム上での行のマージ方法
-
著作権法について
-
pip --versionがエラーになる
-
pythonの実行に関する質問
-
COPYコマンドで、最後に1文字...
-
uwscでPauseキーが押されたら、...
-
Fortranでシステム時刻をカレン...
-
PowerAutomateで運賃検索がした...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
プログラム言語
-
vba クリップボードクリアにつ...
-
プログラミングについて
-
画像生成AIのプロンプトの作り...
-
自作scratch アニメの商用利用
-
今のプログラミング言語
-
CSVファイルの複数行削除
-
Python... 環境設定 初心者です...
-
Python 3.12.2 か一番最新のパ...
-
数学、プログラミング、物理、...
-
パイソンのソースコードをChatG...
-
pythonの実行に関する質問
-
pip --versionがエラーになる
-
Geminiフォーム 画像生成で 人...
-
OS入ってる機器のソフト・アプ...
-
Google ColaboでGUI作成
-
google Colabでmatplotlibの描...
-
Webサイト内に埋め込んだmp4動...
-
初心者powershellのPS1ファイル...
-
VBAでパワーシェルを実行したい...
おすすめ情報
では、関数から戻るの「から戻る」とはどこに戻るのかは、考えなくても良いと言うか、省略されていると言う事でしょうか?後、eaxの「0」は、なぜ使えるのでしょうか?教えて頂けると幸いです。
迅速な回答ありがとうございます!では、eaxの「0」を使用したのはなぜでしょうか?教えて頂けると幸いです。
当該のプログラム内でサブルーチン XX を呼び出したルーチン
だからね。
のそのルーチンは何なのでしょうか?教えて頂けると幸いです。
分かりました。所で、eaxの「0」をreturnの戻り値として使ったのはなぜでしょうか?教えて頂けると幸いです。