在Assembly x86中反转数组

时间:2016-11-12 21:40:52

标签: arrays loops assembly x86 reverse

我决定学习汇编(使用emu8086),我想学习如何反转数组。 所以,我想将这段代码从C转移到汇编:

   void reverse(int len, char *str)
    {
      int i;
      char temp;

      for (i=len-1; i >= len/2; i--)
       {
         temp = str[i];
         str[i] = str[len-1-i];
          str[len-1-i] = temp;
       }
   }

这是数组

   chrs db  'A','N','E','X','A','M','P','L','E','$'

这是主要的

    mov ax, offset chrs
    push ax
    push 9
    call reverse

到目前为止,我可以自己处理它,直到我进入循环部分。 我学会了如何编写一个简单的循环,我也使用了这个 - While, Do While, For loops in Assembly Language (emu8086)

所以,我的主要问题是做反向功能。你能告诉我我是如何使用它的吗? 感谢。

1 个答案:

答案 0 :(得分:0)

我将向您展示如何以不同的方式在C中编写它。如果你能理解我做了什么,那么一旦你对计算机内存设计有了更好的习惯以及CPU如何使用它,你应该能够稍后进行asm循环。

void reverse(int len, char *str) {
    char *bptr = str;
    char *eptr = str+len-1;
    char temp;

    while (bptr < eptr) {
        temp = *bptr;
        *bptr = *eptr;
        *eptr = temp;
        ++bptr;
        --eptr;
    }
}

通过对每一行使用恰好一条x86指令,可以将此C的循环体转换为ASM,并且可以通过在循环体前面使用两条指令并在其后面使用一条指令来完成初始while。 / p>

您应该只能使用movincdeccmpjaeret和{ {1}}或lea

顺便说一下,如果你想学习ASM,不要记住“如何写循环”的指令,比如某种源列表,这是完全没用的。你需要记住(1)每个指令究竟是做什么的,并通过它来理解循环是如何实现的。

CPU是确定性状态机,并且每条指令确实以简单的确定性方式改变该状态。所以在开始时你有一些状态的CPU,以及某种状态的内存(可能包含一些输入数据,还有你的指令=代码),你知道你想在最后实现什么状态(CPU和内存的状态)内容)。您只需使用指令将初始状态更改为结束状态。

例如,如果您的初始状态是add包含值5,并且您希望以ax结束包含值ax,那么您有多种方法可以实现这一目标,更短的方式(每个只有单一指令):

  • 6
  • mov ax,6
  • mov al,6
  • inc ax

浪费许多指令的荒谬方式可能是:

inc al

这就是为什么记住“列表”是没用的,有很多方法可以达到你想要的状态。

(1)不完全是,即使在了解了x86 asm 20多年之后,我几乎每次写一些ASM时都会检查英特尔指令参考指南。因为细节通常很重要,我必须确保指令完全符合我的预期。