2013-10-03 156 views
0

我有一个包含一个缓冲区:“B”“A”“C”“\ n”和我想换字母“B”和“A” ......x86汇编,交换语法

检查调试器,印刷的4个字节的EBP: 'b' 'A' 'C' '\ N' ....

  1. EBP - 缓冲区
  2. EAX的地址 - 偏移量(当前为0 ),以便Ebp + eax指向缓冲区中的'b'
  3. Ebx - 包含'b'
  4. Edi - 包含'a'

问题是,当我运行应该覆盖在缓冲区中的“B”与“一”的命令:

mov [ebp + eax] , edi  

...我打印缓冲区,它现在包含: 'a''c''\ n'...'b'去了哪里?如果我跑这应该覆盖的“a”中的Buff与“B”的下一个命令,完成交换:

mov [ebp + eax + 1], ebx 

...我打印缓冲区,它现在包含:“A”' b''a''c'...而不是'a''b''c''\ n'...任何人都可以解释这里发生了什么吗?

+4

您只需要移动一个字节,而不是整个寄存器(4个字节)。 –

回答

1

我认为你收到

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

因此复制整个32位寄存器的举动再次

mov [ebp + eax], edi  ; the string now becomes 'ac\n\garbage' 
mov [ebp + eax + 1], ebx ;      'abac' 

这就是你看到后。你应该只复制一个字节,而不是一个双字。但是SI没有相应字节的寄存器名,所以你应该重新安排您注册使用一个共同的字节寄存器,如CL,BL

如果你使用x86_64的则只是复制和SIL和BL

1

OP的关键问题是EDI只能作为32位值移动到内存中。他需要一个可以按照8位值移动的寄存器,正如Luu所建议的;这将是AH,AL,BH,...。 AL最容易使用,它是EAX的“一部分”。

如果OP会修改他的代码以便EDI包含偏移量,并且EAX包含该字符,那么遵循Luu的建议将很容易。然后以存储一个字节所需要的指令是

mov byte ptr [ebp+edi],al 

的“字节的ptr”告诉你期望移动8,而不是32位汇编器;这在技术上是不必要的,因为使用AL清楚地表明只使用8位,但对读者有帮助。