• 汇编语言学习笔记(五)


    十六、数组

    数组的基本表示方法

    numary sdword 2,5,7

    numary数组中有三个元素,为sdword类型,分别为2,5,7

    empary sdword ?, ?,?

    empary数组为sdword类型元素,未初始化。

    如果数组元素很多可通过

    zeroary sdword 100 dup(0)

    zeroary数组中有100个0

    empary sdword 3 dup(?)

    empary 数组中有3个未初始化的sdword类型数据

    mov eax, numary+8; 表示把数组numary第3个元素放入eax中

    sdword为四字节,numary+0表示numary首地址,也是第一个元素地址,以此类推,numary+8为第三个元素首地址。

    mov numary+0, eax; 将eax内容放入数组第一个元素中。

    出了采用数组首地址+偏移地址方式,可以采用ebx基址寄存器进行数组索引。

    访问numary第三个元素

    mov ebx, 8;ebx存储8

    mov eax, numary[ebx];访问numary偏移8字节的元素,也就是第三个元素,放入eax中。

    举个例子C语言:

    sum = 0
    for(i = 0; i < 3; i++)
    {
      sum +=numary[i];
    }

    汇编语言:

    mov sum, 0
    mov ecx ,3
    mov ebx, 0
    .repeat
    mov eax, numary[ebx]
    add sum, eax
    add ebx,4
    .untilcxz

    除了使用基址寄存器ebx,还可以使用寄存器esi和寄存器edi进行索引,

    esi为源索引寄存器,edi为目的索引寄存器。

    第一种方法

    mov ebx,4

    mov eax,numary[ebx]

    第二种方法

    mov esi, offset numary+4

    mov eax,[esi]

    第二种方法先将numary+4的地址放入esi中,

    然后[esi]取出esi指向的地址空间的数据,也就是numary+4地址空间里的数据

    将数据放入eax中。

    两种方法的效果图:

    除了上述两种方法,还有第三种方法

    lea esi, memory+4

    mov eax, [esi]

    lea 和offset的区别:

    offset 是在编译时将地址写入esi

    lea是动态写入,每次运行时将地址写入esi中。

    去实现如下代码:

    j=n-1;
    for(i=0; i < n/2; i++)
    {
        temp=numary[i];
        numary[i] = numary[j];
        numary[j] = temp;
        j--;
    }

    通过汇编实现:

    mov ecx,n
    sar ecx,1
    lea esi,numary+0
    mov edi, esi
    mov  eax,n
    dec eax
    sal eax,2
    add edi, eax
    .repeat
    mov eax, [esi]
    xchg eax, [edi]
    mov [esi], eax
    add esi,4
    sub edi,4
    .untilcxz

    数组还有两个指令,lengthof表示数组元素的个数

    sizeof表示数组总共占用多少字节。

    前面的代码可以通过这两个指令修改

    mov ecx, lengthof numary
    sar ecx,1
    lea esi, numary+0
    mov edi, esi
    mov eax, sizeof numary
    sub eax,4
    add edi, eax
    .repeat
    mov eax,[esi]
    xchg eax, [edi]
    mov [esi], eax
    add esi, 4
    sub edi,4
    .untilcxz

    十七、数组总结

    1 esi 为源索引寄存器,主要用于从esi指向地址空间取出数据

    2 edi为目的索引寄存器,主要用于向edi指向地址空间写入数据

    3 esi和edi存储的为地址,[esi]和[edi]为他们指向的地址空间存储的数据

    4 可以通过mov edi, esi将esi寄存器存储的地址放入edi中,因为两个操作数都是寄存器

    5 不可以使用mov [edi],[esi];因为两个操作数都为内存,这是汇编指令mov不允许的。

    6 寄存器ebx为基址寄存器,可通过   数组名[ebx]取出数组首地址偏移ebx存储的字节数的元素。

    7 offset操作符的mov指令,如mov eax, offset sumary+4 是将sumary首地址偏移4字节地址写入eax,

      此时eax存储的是第二个元素首地址,他是静态的获取地址,而lea是动态的获取地址

    8 lengthof用于计算数组元素数量,sizeof用于计算数组总共占用多少字节。

    数组的介绍到此为止,下一篇是字符串的介绍

    我的公众号:

  • 相关阅读:
    Qt Examples Qt实例汇总
    [转帖] VS集成Qt环境搭建
    GTKmm 学习资料
    Programming with gtkmm 3
    CvMat and cv::Mat
    [LeetCode] Longest Consecutive Sequence 求最长连续序列
    [转帖] CvMat,Mat和IplImage之间的转化和拷贝
    [LeetCode] Sum Root to Leaf Numbers 求根到叶节点数字之和
    [LeetCode] Palindrome Partitioning II 拆分回文串之二
    [LeetCode] Palindrome Partitioning 拆分回文串
  • 原文地址:https://www.cnblogs.com/secondtonone1/p/6700449.html
Copyright © 2020-2023  润新知