2017-11-30 5 views
2

私は本書からこのアセンブリプログラムを勉強していましたが、私はそれについて質問します。このプログラムの目的は、単にstring1をstring2にコピーすることです。私の質問は、次の2つの命令に関する:アセンブリーストリング命令DSとESをリアルモードで登録

mov AX,DS   
mov ES,AX 

私はそれらなしで参照、プログラムが正しく動作しませんが、私はそれはあなたが必要なすべてのだろう、string2のにESI string1とするとEDIを指すことによって考えているだろうする。次に、ESIEDIを増分して1文字ずつ移動します。 DSの正確な内容と、それをESに移動する必要があるのはなぜですか?

.DATA 
string1 db 'The original string',0 
strLen  EQU $ - string1 
.UDATA 
string2 resb 80 
.CODE 
    .STARTUP 
    mov AX,DS   ; set up ES 
    mov ES,AX   ; to the data segment 
    mov ECX,strLen  ; strLen includes NULL 
    mov ESI,string1 
    mov EDI,string2 
    cld     ; forward direction 
    rep movsb 
+0

この16ビットコードですか?それは本当にCX、DS、DIを使うべきです。そして、あなたは 'mov ESI、offset string1'と' mov EDI、string1'を意味すると思いますか? –

+0

これは本から来ており、本は指定していません。 – Rubiks

+0

windows dosboxとnasm – Rubiks

答えて

3

EDI使用ES:EDIを使用するすべての文字列指示。 DS、しかしmovs/stos/scas/cmps (with/without rep/repz/nz) all use es:ediEDI(のような[edi])デフォルトを使用して(またはdiまたはrdi

明示的なアドレッシングモード。 lodsds:esiのみを使用します。 (​​は「作品」が、まれに有用である。CX = 0または1で、それが原因でloopとは異なり、repチェックcxデクリメントする前に、遅い条件付き負荷として動作することができます。)

注意にもかかわらずscasが読み取り専用であること(r|e)diを使用します。これはlodsとよく一致します。あるアレイからのロードをlodsscasと異なる配列と比較します。 (オプションとして、比較の前に何らかの種類の処理を(r|e)axとする)。


通常、32ビットアドレスを使用できる場合、すべてのセグメントのベースとリミットが同じフラットメモリモデルがあります。あるいは、NASMで.COMフラットバイナリを作成する場合、すべてのセグメントが同じ値を持つ小さなリアルモードメモリモデルがあります。 @ MichaelPetchのコメントon this answeron the questionを参照してください。 ESを設定せずにプログラムが動作しない場合、あなたは何か変なことをしています。 (多分どこかesをつかうような?)

注16ビットモードでrep movsbアドレスサイズプレフィックスは関係なく、あなたがedi代わりのdiを書くために、オペランドサイズの接頭辞を使用するかどうかの、CXを使用しDS:SI、およびES:DIなしています。しばしば


またその担当者ストリング命令(および特に非担当者バージョンを)されている注意**ないものを行うための最速の方法。それらはコードサイズには適していますが、しばしばSSE/AVXループよりも遅いです。

rep stosおよびrep movsは、16または32バイトのチャンク(またはSkylake-AVX512では64バイト)で保存またはコピーする高速マイクロコード実装を備えています。 Enhanced REP MOVSB for memcpyを参照してください。 32バイトのポインタと中規模〜大規模のバッファサイズを使用することで、最適化されたAVXループと同じくらい高速にすることができます。最近のCPUやアライメントされていないポインタでは、128バイトまたは256バイト以下のサイズでは、AVXコピーループが通常勝ちます。インテルの最適化マニュアルにはこのセクションがあります。

しかし、repne cmpsbは、実装する最も速い方法ではありません。:SSE2またはAVX2 SIMDの比較は、一度に1バイトずつしか比較しないので、(pcmpeqb)です。 (バッファの最後を読み取ることに注意してください。特に、ページ(または、好ましくはキャッシュライン)の境界を越えることは避けてください。)とにかく、repne/repeはIntelまたはAMD CPUで "高速ストリング"

+1

ちょっと混乱している - 詳細情報:文字列命令の "ソース"のような部分 'ds:si 'は、セグメントプレフィックスopcodeで上書きすることができます。つまり、' es lodsb'は '[es :si] '。しかし、 "宛先"のようなものは 'es:di'だけに配線されています。' ds stosb'のようなセグメントプレフィックスは無視されます。 – Ped7g

+0

SIMDの比較には、コードを書くときに特別な注意を払わない限り、メモリ領域の最後を読み取ることができるという欠点があります。これは対処するのが厄介です。 – fuz

+1

私はより良い質問は、彼がなぜDSにESをコピーする必要があるのか​​という理由でユーザーが環境を使用しているかどうかということです。 NASMはEXEではなくCOMプログラムを生成し、COMプログラムはCS = DS = ES = SSで始まります。個人的に質問は嗅覚テストに合格しておらず、最小限の完全な例ではありません。投稿されたコードは(io.macが必要なので)そのままコンパイルされず、 'org 0x100'指示文を正しく動作させます。 –

関連する問題