- ベストアンサー
ret とretfについて。
chie65535の回答
- chie65535
- ベストアンサー率44% (8567/19468)
x86系CPUは、レジスタが16ビットなので、アドレスも16ビットで記憶しています。 16ビットだと、表現できるのは「0000~FFFF」の範囲だけなので、メモリ空間は64キロバイトまでしか表現できません。 しかし、x86系CPUのアドレスバスは20ビットなので、20ビットのアドレスを、16ビットのレジスタ2つの組み合わせで表す事にしました(実アドレス空間は0x00000~0xFFFFFまでの1メガバイトです) 具体的には「セグメントレジスタ×16+オフセットレジスタ」という計算で、20ビットの実アドレスを表現しています。 この時、16倍される上位の方を「セグメント」、そのまま足される下位の方を「オフセット」と言います。 つまり、1メガバイトのアドレス空間を「64キロバイトごとの空間」に分割して、表現しているのです。この「分割」の上位アドレスを表すのが「分割」を意味する「セグメント」なのです。 例えば、セグメント0x1F53、オフセット0x0106の場合、実アドレスは0x1F636になります。 X86系CPUの「プログラムカウンタ(今、どこのメモリのプログラムを実行しているかを覚えているレジスタ)は、セグメントの方はCSレジスタ、オフセットの方はIPレジスタが保持しています。 RET命令を実行すると、CPUは「戻り場所を記憶しているメモリ」から16ビット分のデータを取り出して、それをIPレジスタに代入して、IPレジスタの指す場所から実行を再開します。 RETF命令を実行すると、CPUは「戻り場所を記憶しているメモリ」から16ビット分のデータ2つを取り出して、それをCSレジスタとIPレジスタの2つに代入して、CSとIPレジスタの指す場所から実行を再開します。 なので、サブルーチンを呼び出す際は、呼び出されるサブルーチンがRETで終わっているかRETFで終わっているかを意識して、NEAR CALLで呼ぶべきかなのかFAR CALLで呼ぶべきなのかを明確にしないといけません。 RETで終わってるサブルーチンはNEARで呼ぶ、RETFで終わっているサブルーチンはFARで呼ぶ必要があります。間違うと、帰るアドレスが違ってしまい、プログラムが暴走します。
関連するQ&A
- retやretfについて。
アセンブリ言語では、retとretfとはどういう事でしょうか?nearリターンとfarリターンの違いは何でしょうか?教えていただけないでしょうか?すみません。 nearは現在のセグメント内で戻る。 farの方は、セグメントも復元して戻る。 の違いだと。 直訳するとセグメントは分割ですが、nearは現在の分割に戻る。farは、分割も復元して戻る。という意味になると思うのですが、どういう事でしょうか?差し支えなければ教えていただけないでしょうか?すみません。
- ベストアンサー
- その他([技術者向] コンピューター)
- 機械語に直すことについて。
(機械語データ) (アセンブリ言語) b8 57 61 6b 61 mov $0x616b6157,%eax 53 push %ebx 50 push %eax ba 04 00 00 00 mov $0x4,%edx bb 01 00 00 00 mov $0x1,%ebx b8 04 00 00 00 mov $0x4,%eax 89 e1 mov %esp,%ecx cd 80 int $0x80 58 pop %eax 31 c0 xor %eax,%eax 5b pop %ebx c3 ret これのintと movとxor の機械語が分かりません。後、retの機械語が、farなのかnearなのかも分かりません。教えていただけないでしょうか?すみません。
- ベストアンサー
- その他([技術者向] コンピューター)
- アセンブリ言語についてと言語の違いについて。
高水準と低水準言語の違いは、まず、マシン語の2進数の羅列では分からないからアセンブリ言語が生まれ、 アセンブリ言語よりさらに人間が理解できる言語が、C言語やBASICなどでしょうか?教えていただけないでしょうか?合っていますでしょうか?
- 締切済み
- その他([技術者向] コンピューター)
- 囚人のジレンマゲーム C言語
囚人のジレンマゲームをC言語で作りました。そのうちのこの部分を変えて、相手が協調の際に9回まで裏切り、後は全部協調とするにはどうしたらいいのでしょうか。 int you(int bc) //PLAYER1 { int ret; /* if(bc==COOPERATION){ret=COOPERATION;} else{ret=DEFECTION;} */ ret=DEFECTION; return(ret); }
- 締切済み
- C・C++・C#
- アセンブリのプログラムです。
アセンブリのプログラムで質問があります。cのプログラムのオブジェクトファイルを生成して、objdumpというコマンドでアセンブリ言語を表示させてみたのですが、全然分からなくて、困っています 。どうか、アセンブリプログラムの、解説をよろしくお願いします。できれば、1文1文解説してもらえるとありがたいです。あと、スタックの動き、確保などの解説もあるとありがたいです。よろしくお願いします。 cのプログラム int fact(int p) { if(p<=1) return 1; else return fact(p-1); } アセンブリのプログラム push %ebp mov %esp,%ebp sub $0x8,%esp cmpl $0x1,0x8(%ebp) jg 15 <_fact+0x15> movl $0x1,-0x4(%ebp) jmp 24 <_fact+0x24> mov 0x8(%ebp),%eax dec %eax mov %eax,(%esp) call 0 <_fact> mov %eax,-0x4(%ebp) mov -0x4(%ebp),%eax leave ret nop nop nop
- ベストアンサー
- その他(プログラミング・開発)
- デバイスドライバー作りに関する質問
デバイスドライバーでは、アセンブリ言語を使う部分があるとの事で、アセンブリ言語の技術を伸ばす為、デバイスドライバーを作ってみようと思うのですが 実際はどれくらいアセンブリ言語を使うのでしょうか またはデバイスドライバーというのは組み込みの分野ですか?
- ベストアンサー
- その他(プログラミング・開発)
- 低水準言語について。
低水準言語があるのは、例えば、この人は、これができた。あの人は、これができた。しかし、一つだけできたのでは、意味がないから、それを総称(合併)して、アセンブリ言語という名前になった。で、 アセンブリ言語がなければ、C言語などの高水準言語は、誕生していなかった。という事で、合っていますでしょうか?教えていただけないでしょうか?すみません。
- 締切済み
- その他([技術者向] コンピューター)
- C言語の関数の質問です
C言語の質問です 最近C言語を始めました。以下の問題がわかりません。 int型の数値を入力して結果をdouble型の戻り値を返すことはできないのか。 関数の値のやり取りでも暗黙の型変換や明示的な型変換はできるのか。 #include <stdio.h> double square(int x); int main(void) { int num; double ret; scanf("%d",num); ret = square(num); printf("%ld",ret); return(0); } double square(int x){ return(x*x); }
- ベストアンサー
- C・C++・C#
お礼
RET命令を実行すると、CPUは「戻り場所を記憶しているメモリ」から16ビット分のデータを取り出して、それをIPレジスタに代入して、IPレジスタの指す場所から実行を再開します。 RETF命令を実行すると、CPUは「戻り場所を記憶しているメモリ」から16ビット分のデータ2つを取り出して、それをCSレジスタとIPレジスタの2つに代入して、CSとIPレジスタの指す場所から実行を再開します。 ここを詳しく教えていただけないでしょうか?すみません。
補足
しかしから詳しく教えていただけないでしょうか?すみません。