2017-05-29 7 views
1

私は非常に厳密に制限されたASMコードを書いています。これらの冗長な末尾のゼロを削除することはできますか?

お知らせNASMによって生成されたオペコードのこのグループ:

8AA4241C020000 mov ah,[esp+0x21c] 

および類似:

051C020000 add eax,0x21c ; 4 extra 0's! 
8D84241C020000 lea eax,[esp+0x21c] ; Brutal! 

は、あなたがAにオフセット15bitを適用しようとするプロセッサと通信する方法があります32ビットレジスタ、そしてそれ自身の0パディングを理解させますか?

いくつかのガイダンスについてはhttps://c9x.me/x86/html/file_module_x86_id_176.htmlまでコーディネートしています。余分な2バイトはここにかそこらで実際に私の人生を救うでしょう!

も受け入れ:手への道がある場合

mov eax,[esp+0x21c] 
push eax 

:それを小さくする声明を書き換える

代替方法を、最終的に私はこのインスタンス内のためつもりだことのようなものですそれを超小型にするためにエンコードして、私はその技術を見たいと思っています。

+0

そこにはLEAの例があります; – baordog

+2

プロセッサマニュアルには、利用可能なものが記載されています。 16ビットオフセットは、16ビットレジスタでのみサポートされています。あなたは手のエンコーディングについて何を意味するか分かりません。あなたは何かを作ることができないのではありません。 –

+0

レジスタの上部( 'xor ebx、ebx')をゼロにしてから、' mov bx、21c'の中で16bitの値を移動し、 'ebx'を使わずに)必要に応じて使用することができます(' add eax、 ebx)。 xorは無料ではありませんが、このトリックを複数回実行している場合は... –

答えて

0

プロセッサと通信する方法はありますか?32ビットレジスタに15ビットのオフセットを適用する方法はありますか?

第利用できる命令エンコーディングは、インテルのマニュアル(オンラインで入手でき、様々な場所であるのオンライン版; タグのwikiのリンクを参照)に記載されています。 MOVの場合、オフセットサイズはレジスタサイズと一致します。プロセッサは、16ビットレジスタに入力するときに16ビットのオフセットのみを使用します。 15ビットオフセットを得る方法はありません。

Raymond Chenが言うように、「あなた自身のカスタムエンコーディングを作ることはできません」

一部の命令では、一部のモードで符号拡張ビットがあります。

確かに、これがあなたにどのように役立つかわかりません。あなたの目標は、命令のサイズを減らすことです:オフセットサイズの解釈を変更するために、余分な16ビットのオペランドサイズのプレフィックスを追加することは、そうするのを助けることにはなりません。

一般に、オリジナルと同等の命令をエンコードする方法が短かった場合、アセンブラはそのエンコードを放出します。 確かに NASMはmulti-pass optimization option(デフォルトで有効)です。

ここで2バイト余分に私の人生を救うでしょう!

これは効果的に保存できる場所の1つではありません。

David Wohlferdが既に提案しているように、これを繰り返し実行する場合は、レジスタ(XOR reg, reg; 2バイト)を事前に消去してコードサイズをわずかに圧縮し、reg-レジスタMOV(各2バイトのみ)をクリアし、すでに上位16ビットがクリアされているレジスタに16ビットのMOVを実行します。

多数のレジスタを持つISAを扱う場合、特定のプロシージャのコンテキストで0を含むように専用にするのが比較的一般的です。多くのISAは、専用のゼロレジスタを持つことでこれをさらに引き継ぎます。 x86でもこれを行うことができますが、ISAがどのようにレジスタ制限されているかを考えると、通常は悲観的です。しかし、他のすべてのサイズに対して最適化を行っている場合は、時には意味をなさないことがあります。 (それでは、メモリに溢れ出るようになるかもしれないので、コードはで少なくとも 2バイトごとに膨らみます)

実際には、私はそこに賭けていますあなたの命令の大きさで浪費されているコードでは、他にもたくさんの場所があり、大幅な削減が実現できます。サイズを減らすことを目指してコードをレビューしたい場合は、Code Reviewに質問を投稿することを検討してください(もちろん、作業コードがあると仮定します)。

2バイトの節約が重要なコードを書いている状況は本当によくわかりません。たぶん、あなたは512バイト以内に収まる必要があるブートローダを書いているでしょうか?その場合、ほとんどの人が行うことは、複数段のブートローダーを作成することです。最初の段階では512バイトに制限されているため、このような制限がない第2段階が呼び出されます。

0

あなたがゼロ上位24ビットを有するいくつかのレジスタを有することになる場合には、例えば(EAXのためのゼロ)は、2つのバイトを削り取ることが可能である:

; additional 2 bytes ruining the saving, if you don't have zero reg. 
; b0 87     mov al,0x87 

; 5 byte fetch of value 
b0 87     mov al,0x87 
8a 24 84    mov ah,BYTE PTR [esp+eax*4] 

またはあなたはいくつかの低値104を知っているなら..540(一部だけそれらの適した)他のいくつかのレジスタに、あなたはあなたがebx == 104を知っているとしましょう例えば、それによってビットオフセットを下げることがあります。

8a 64 9c 7c    mov ah,BYTE PTR [esp+ebx*4+(0x21C-104*4)] 

これが本当のサイズの挑戦になる場合は、コード全体を投稿する必要があります。なぜなら、(そして非常に頻繁には)狂った方法非常に予期しない、ほとんど想像もできない方法でサイズを保存します。

関連する問題