0

次を含むバッファがあり'bac\n'、文字を交換しようとして'b'います'a'

デバッガーをチェックしたところ、ebp が指すアドレスに 4 バイトが出力されました。'bac\n'

  1. ebp - バッファのアドレス
  2. eax - オフセット (現在は 0)で、バッファ内のをebp + eax指す'b'
  3. ebx - 含む'b'
  4. edi - 含む'a'

'b'問題は、バッファ内の を次のように上書きする命令を実行するときです'a'

mov [ebp + eax], edi

...次に、バッファを印刷すると、次が含まれるようになりました'ac\n'。どこに行った'b''a'バッファ内のを で上書きするはずの次の命令を実行すると'b'、スワップが完了します。

mov  [ebp + eax + 1], ebx

...その後、バッファには以下が含まれるようになりました'abac':'abc\n'

ここで何が起こっているのか誰でも説明できますか?

4

3 に答える 3

2

表示されていない部分で、以前に32ビットレジスタ全体をコピーしたと思います

; copy 4 bytes from ebp + eax to ebp + eax + 3
mov ebx, [ebp + eax]     ; ebx = 'bac\n'
mov edi, [ebp + eax + 1] ; edi = 'ac\n<garbage>', which is ebp + eax + 1 to ebp + eax + 4

したがって、キャラクターをメモリに戻した後

mov [ebp + eax], edi     ; the string now becomes 'ac\n<garbage>'
mov [ebp + eax + 1], ebx ;                        'abac\n' (5 bytes)

これはあなたが見るものです。1 つのダブル ワードではなく、 1 バイトだけをコピーする必要があります。ただし、DI には対応するバイト レジスタ名がないため、レジスタの使用法を CL/BL などの下位バイト レジスタに再配置する必要があります。

mov  bl, [ebp + eax]
xchg [ebp + eax + 1], bl ; simple, but not efficient
mov  [ebp + eax], bl

空きレジスタが残っていない場合は、ビット単位の操作を使用する必要があります

x86_64 を使用する場合、DI の低い部分は と評価できDILますが、1 バイト長くなります。

于 2013-10-03T07:32:32.403 に答える
1

OP の主な問題は、EDI が 32 ビット値としてのみメモリに移動できることです。Luu が提案したように、8 ビット値として移動できるレジスタが必要です。これは、AH、AL、BH、... になります。AL は最も使いやすく、EAX の「一部」です。

EDIにオフセットが含まれ、EAXに文字が含まれるようにOPがコードを修正する場合、Luuのアドバイスに従うのは簡単です。次に、バイトを格納するために必要な命令は次のとおりです。

mov byte ptr [ebp+edi],al

「byte ptr」は、32 ビットではなく 8 ビットを移動することを期待していることをアセンブラーに伝えます。AL を使用すると、8 ビットのみを使用する必要があることが明確に示されるため、技術的には不要ですが、読者には役立ちます。

于 2013-10-03T10:06:03.027 に答える