【问题标题】:Reverse an array in Assembly x86在 Assembly x86 中反转数组
【发布时间】:2017-03-26 20:42:58
【问题描述】:

我决定学习汇编(使用 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)

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

【问题讨论】:

    标签: arrays loops assembly x86 reverse


    【解决方案1】:

    我将向您展示如何以不同的方式用 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;
        }
    }
    

    这个C的循环体可以通过每行只使用一条x86指令来转换为ASM,并且初始while可以通过在循环体之前使用两条指令和在循环体之后使用一条指令来完成。

    您应该能够仅使用 movincdeccmpjaeretleaadd 来编写所有这些内容。


    顺便说一句,如果你想学习 ASM,不要像某种源代码列表那样通过指令来记住“如何编写循环”,那是完全没用的。您需要记住 (1) 每条指令的具体作用,并了解循环是如何通过它实现的。

    CPU 是确定性状态机,每条指令都会以简单的确定性方式改变该状态。因此,在开始时,您的 CPU 处于某种状态,内存处于某种状态(可能包含一些输入数据,还有您的指令 = 代码),并且您知道最终要达到的状态(CPU 和内存的状态内容)。您只需使用指令将初始状态更改为结束状态。

    例如,如果您的初始状态是 ax 包含值 5,并且您希望以包含值 ax6 结束,那么您有几种方法可以实现这一点,更短的方法(每个只有一条指令)存在:

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

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

    xor ax,ax
    dec ah
    shr ax,14
    add ax,ax
    

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-11
      • 2017-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多