、cs
、ds
とes
セグメント全てがfs
とgs
セグメントは、異なる目的のために使用される0
で同じ値を保持します。現在のプロセスの32ビットスレッド情報ブロックに
のWindows
fs
ポイント。
gs
は、現在のプロセスの64ビットTIBを指します。
Linux 32ビット・カーネルfs
で
はCPUごとのデータ領域の塩基です。 64ビットカーネルgs
では、pda(プロセッサデータ領域)を指しています。 pdaは 単一構造ですが、per-cpuデータはcpu単位で の変数が配置されるセクションです。
fs
は、64ビットオペレーティングシステム(WoW64など)で32ビットコードを実行する場合に使用されます。
特殊な目的を持っていたレジスタはx86でしたが、現在ほとんどのレジスタは汎用です。
rsi
は、いかなる目的にも使用できます。
文字列命令でのみ、特別な意味を持ちます。
この文脈では、ソース(例えば、movsb)を指すために使用されます。
それで機能を区別することはできますか?
セグメントプレフィックスをプレフィックスとして使用します。
mov rsi,[rax] // rsi = memory(rax).
xor eax,eax //rax =0 (remember 32 bit instructions zero extend)
mov rsi,[gs:rax] //load the first 8 bytes of the 64-bit TIB into rsi.
LEAについてリーは、それが単にフラグを変更せずに計算を行い、メモリにアクセスしません。
多くの場合、これらの計算にはポインタの計算が含まれますが、一般的な算術演算でもあります。
セグメントプレフィックスをleaの前に置くことは意味をなさないので効果はありません。
x86_64の「小さなメモリモデル」とは何ですか?これは16bモードでこのように使用されましたが、セグメント値は物理アドレスの一部です(最後の20bアドレスのビット4〜19に追加されます)。 |あなたがそのようなコードにポインタを渡す方法は明らかではない( 'rax'では?)、 'fs'が' ds'と異なるならば、それぞれの 'mov'は異なる論理メモリアドレスを使用します(メモリはそのようにマップされていれば同じ物理アドレスにマッピングされますが、最初の 'fs:rax'、他の' ds:rax' ...何かがx86_64(ディスクリプタテーブルへの何らかのインデックス?)で意味するもの) – Ped7g
どちらのアセンブリステートメントも場所から64ビットの値を読み込みますメモリに格納し、RSIに格納します。いずれのステートメントも、その関数のアドレスが以前に読み取られた場所に格納されていない限り、関数のアドレスをRSIにロードしません。第1の命令によって読み取られるメモリ内の位置は、線形アドレス「FS.base + RAX」であり、ここで、「FS.base」はFSセグメントのベースである。第2のメモリによって読み取られるメモリ内の位置は、線形アドレス「RAX」にある。 DSセグメントのベースは、64ビットモードでは常に0です。 –
@ Ped7g別のトピックで「小さなメモリモデル」を見たとき、セグメントレジスタが同じ値を共有していることを意味します。実際には、アドレスが1つのレジスタから渡されるため、関数がどのセグメントレジスタを使ってデータにアクセスすべきかを知っています。私はコードが混乱して申し訳ありません... – liubenxi