2

私は組み立てを学び始めました。私はこれらの線に出くわしました。

;*************************************************;
; Second Stage Loader Entry Point
;************************************************;

main:
   cli  ; clear interrupts
   push cs ; Insure DS=CS
   pop ds

ここでコードの2行目で、コードセグメントはスタックにプッシュされます(私はこれだと思います)。私はそれを多くのコードで見ました。なぜこれを行う必要があり、DS = CSをどのように保証するのですか?3行目でDSがスタックから飛び出します(私はこれだと思います)。なぜそれが行われるのですか?スタックから飛び出しているということは、以前はスタックにプッシュされていたことを意味します。そのためのコードはありません。誰かが私にこれをすべて説明できますか?前もって感謝します。

4

5 に答える 5

4

これpush csを保証するのはそれではなく、それを行うpush cs; pop ds;組み合わせです。

最初の命令はの現在の値をスタックにコピーしcs、2番目の命令はその値をスタックから引き出してdsレジスタに入れます。


詳細情報の要求に応じて、次のスタックとレジスタから始めましょう。

stack=[1,2,3], cs=7, ds=6

push cscsレジスタの値をスタックにプッシュします。

stack=[1,2,3,7], cs=7, ds=6

後、スタックから値をポップしてレジスタpop dsに入れます。ds

stack=[1,2,3], cs=7, ds=7

そしてそれは基本的にそれです。


命令でセグメントレジスタ間を転送できたかどうか、頭のてっぺんを思い出せmovません(そうではないと思いますが、間違っている可能性があり、プッシュ/ポップシーケンスが必要になります)。このリンクは、次のことを確認しているように見えます。送信元宛先movの両方としてセグメントレジスタを使用するオプションはありません。

しかし、そうであったとしても、アセンブラコーダーは、たとえば、xor ax, ax代わりに使用するなど、速度またはコンパクトコード(あるいはその両方)のいずれかのために、より適切な命令を選択することがよくありました。mov ax, 0

于 2010-11-05T06:58:55.553 に答える
4

csdsは単なるレジスタであり、プレースホルダー/変数とほとんど同じです。レジスタの詳細については、こちらを参照してください。2行目では、push csこれはのコンテンツをcsスタックに配置し、次の行ではpopに戻すことを意味しますds

だから今起こったことはあなたがにコピーcsしたということでしたds

push「これをスタックの一番上に置く」という命令です

pop「スタックから最上位の値を取得する」という命令です。

一度実行するとpop、値はスタックに保存されなくなります。

于 2010-11-05T06:59:56.383 に答える
1

'このレジスタをスタックにプッシュし、スタックをこのレジスタにポップする'は、MOV ax、dxなどのMOV命令を使用して実行できる場合があります。ただし、一部のレジスタ間MOV命令は命令セットで使用できず、IIRC MOV ds、csは使用できません。それが、それをメモリ(まあ、実際にはキャッシュ)に入れて、それを読み戻す理由かもしれません。

于 2010-11-05T07:29:24.867 に答える
0

CSの値をスタックにプッシュしてDSにポップすることにより、DSがCSと同じ値を持つようにします。

しばらくアセンブラでプログラミングしていませんが、あるセグメントレジスタから別のセグメントレジスタに直接移動する方法はないと思いました。

スタックはデータの山として見ることができます。あなたは何かを上に押して、それを山から飛び出すまでそこにとどまります。このようにして、スタックを使用してデータを交換できます。ただし、ほとんどの場合、データを保存するために使用するため、レジスタを他の目的に使用して、後でコンテンツを復元できます。

これは、コードを実行するときに発生します。

1)初期状況

CS has value X
DS has value Y
Stack has ....

2)CSをプッシュ

CS has value X
DS has value Y
Stack has ...., X

3)ポップDS

CS has value X
DS has value X
Stack has ....

しかし、セグメントレジスタとは何ですか。昔は、8086には16ビットのアドレスレジスタがありましたが、20ビットのアドレス空間がありました。そこで、セグメントレジスタを使用して、セグメントレジスタに16を掛けて、両方を20ビットスペースに結合し、メモリ位置を追加しました。スペースを節約するために、ニアポインター(セグメント内にジャンプするセグメントなし)とファーポインター(セグメントあり)がありました。

80286保護モードの導入により、セグメントレジスタはセグメント記述子として再利用されました。彼らは、実空間に到達するのに十分な情報を提供するメモリの場所を指し示しました。しかし、今では線形アドレス空間があります(実際のメモリに仮想的にマッピングされています)。

于 2010-11-05T06:59:52.397 に答える
0

書かれたコメントのように、push csそれからそれpop dsを確実にしds=cs?ます。push cscsの値をスタックの一番上に置き、その値をスタックpop dsから削除して、に格納しdsます。

于 2010-11-05T07:00:53.107 に答える