• ベストアンサー

ret とretfについて。

AsarKingChangの回答

回答No.3

>直訳するとセグメントは分割ですが、nearは現在の分割に戻る。farは、分割も復元して戻る。という意味になると思うのですが、どういう事でしょうか?差し支えなければ教えていただけないでしょうか? すみません。 英語的にも、認識としてもそれであってますよ。 32ビットだと、話が面倒なので16ビットモードで説明しますが。 call 0x1234 これは、今いるセグメント内の「1234番地をコールしますよね」 しかし、16ビットは、65536バイトしかありません。 初代8086は、1MByteのメモリを搭載可能でした。 しかし、16ビットでは、1MBをアクセスできないのですよ。 なので、セグメントという「区画わけ=部屋分け」=つまりは分割 する概念が入りました。 同じ、65536=64KB内にある、関数や番地は「Near」と呼ばれ 直接値を書けばジャンプなりコールできます。 しかし「それより外はどうするの?」 ということになり、16バイトを1つと数える セグメントが導入されました。 0000:0000=これは、0番地 0000:0010=これは、16番地こっちはNear 0001:0000=これも、16番地これはFarになる。 で、16ビットx16を1として数える=65536x16=1MB になったのです。 なので、 call near 0x1234 これは、SS:SPレジスタに「次の番地をスタックに入れて0x1234番地にジャンプ」する命令 ret スタックから1つの値を取り出す=これが、「次の番地」 そこにジャンプする。 となります。 今度は、 call far 0x1234:0x5678 この場合はSS:SPレジスタ位置に「現在のCSと次の番地を入れてから、CS=1234をセットした上で、0x5678へジャンプ」する命令になります。 なぜ、retが2つあるのかは、これでわかったと思いますが。 call far の後、retすると、上の例では、本来の位置ではなく、 CS=1234のままで、この命令の次の番地の「下位16ビットに飛んでしまいます」 これを避けるための命令がretf ってことです。 なお、ジャンプ命令と、コール命令をごちゃごちゃに書いてますが。 実は「同じ」です。 mov ax,offset next push ax jmp function :function ret このRET命令がaxに入れていたnextの番地を復元してそこにジャンプ :next ここにきます。 要するに、callとjmp命令は、スタックを使うか使わないかだけで、 同じ物なんです。 なお、スタックというのは、SP(スタックポインタ)ですが、 これも、16ビットなので、当然64Kしかないので、 これにもSS(スタックセグメント) を補うことで、1MB空間を表せるように拡張されています。 CS:PC CS=コードセグメント:PC=プログラムカウンタ これが、プログラム用の、セグメント データは、 DS:データセグメント(何もしなければ常にDSを指してます) と、用途ごとにセグメントが複数あるのもこのためです。 そうしないと、 「今いるセグメントのデータしか読み書きできない」為です。 特殊なもので、用途が決まっていないESなどもあります。 これらは、    mov ax,[0x1234] これは、DSセグメント内の0x1234番地にあるデータを16ビット取り出せ!の命令    mov ax,es:[0x1234] これは、ESセグメント内の0x1234番地にあるデータを16ビット取り出せ!の命令 (これをセグメントオーバーライドと言います) それが「さらに複雑になってページという扱いになってる」 286以降のセグメントレジスタです。 なので、説明したくないほど面倒です。 なので、勉強が目的なら、リアルモード(リニア)86で 止めておく方が、いいかと。

zasx1097
質問者

補足

しかしからもう少し詳しく教えていただけないでしょうか?すみません。

関連する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のプログラムのオブジェクトファイルを生成して、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); }