反转Assembly x86中的数组 [英] Reverse an array in Assembly x86

查看:54
本文介绍了反转Assembly x86中的数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我决定学习Assembly(使用emu8086),并且想学习如何反转数组.因此,我想将此代码从C转移到汇编:

I decided to learn Assembly(using emu8086) and I want to learn how to to reverse an array. So,I want to tranfer this code from C to assembly:

   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

到目前为止,我可以自己处理它,直到进入循环部分.我学习了如何编写简单的循环,并且也使用了它-汇编语言(emu8086)中的While,Do While,For循环

So far I can deal with it by myself until I got to the loop part. I learned how to write a simple loop and also I used this - While, Do While, For loops in Assembly Language (emu8086)

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

So,My main problem is doing the reverse function. Can you please show me how I use it? Thanks.

推荐答案

我将向您展示如何以不同的方式用C编写它.如果您了解我的所作所为,那么一旦对计算机内存设计以及CPU如何使用它有了更好的了解后,就应该可以稍后再进行asm循环.

I will show you how it's possible to write it in C in different way. If you can understand what I did, you should be able to do your asm loop later once you get a bit better accustomed to the computer memory design and how CPU works with it.

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 可以通过在循环体之前使用两条指令,在其后使用一条指令来完成它.

The loop body of this C can be converted into ASM by using exactly one x86 instruction for each line, and the initial while can be done by using two instructions ahead of loop body and one instruction after it.

您应该只能使用 mov inc dec cmp jae ret lea add .

You should be able to write all this with only mov, inc, dec, cmp, jae, ret and lea or add.

顺便说一句,如果您想学习ASM,请不要按照指示(例如某种形式的源清单)记住如何编写循环",这是完全没有用的.您需要记住(1)每条指令的确切功能,并了解如何通过该指令实现循环.

BTW, if you want to learn ASM, don't memorize "how to write loop" by instructions, like some kind of source listing, that's completely useless. You need to memorize (1) what exactly each instruction does, and understand how the loop is achieved through that.

CPU是确定性状态机,每条指令都以简单的确定性方式更改该状态.因此,一开始,您使CPU处于某种状态,而内存处于某种状态(可能包含一些输入数据,并且您的指令=代码),并且您知道最终要达到的状态(CPU和内存的两种状态)内容).然后,您只需按照说明将初始状态更改为结束状态即可.

The CPU is deterministic state machine, and each instruction does change that state in simple deterministic manner. So at the start you have CPU in some state, and memory in some state (containing probably some input data, and also your instructions = code), and you know what state you want to achieve at the end (both state of CPU and memory content). And you simply use instructions to change that initial state into the ending state.

例如,如果您的初始状态是 ax 包含值5,并且您想要以包含 6 值的 ax 结尾,则有几个实现方法,较短的方法(每个方法只有一条指令)是:

If for example your initial state is that ax contains value 5, and you want end with ax containing value 6, you have several ways how to achieve that, shorter ones (each has only single instruction) being:

  • 移动斧头,6
  • 动态1,6
  • inc斧头
  • inc al

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

Ridiculous way wasting many instructions can be:

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

这就是为什么记住列表"没有用的原因,有很多方法可以实现所需的状态.

That's why memorizing "listings" is useless, there are many many ways how to achieve the state you want.

(1)不完全是,即使在我知道x86 asm 20多年后,我几乎每次写一些ASM仍在检查Intel指令参考指南.因为细节常常很重要,所以我必须确保说明能够完全按照我的预期去做.

(1) not exactly, I'm still checking the Intel instruction reference guide almost every time I write some ASM, even after 20+ years of knowing x86 asm. Because often the details matter and I have to be sure the instruction will do exactly what I expect it to do.

这篇关于反转Assembly x86中的数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆