`
qdujunjie
  • 浏览: 110373 次
  • 性别: Icon_minigender_1
  • 来自: Mars
社区版块
存档分类
最新评论

汇编语言数组求和代码分析(1)

阅读更多

 

 

是这么一段代码,来自于《Intel汇编语言程序设计》(第四版)

 

 

;----------------------------------------------------------------------------

ArraySum PROC

;

;  Calculates the sum of an array of 32-bit integers.

;  Receives : ESI = the  array offset

;                   ECX = number of elements in the array

;  Returns : EAX = sum of the array elements

;----------------------------------------------------------------------------

 

         push esi        ; save ESI,ECX

         push ecx

         mov eax,0     ; set the sum to zero

L1:

         add eax,[esi] ; add each integer to sum

         add esi,4       ; point to next integer

         loop L1          ; repeat for array size

 

         pop ecx         ; restore ECX,ESI

         pop esi

         ret                 ; sum is in EAX

ArraySum ENDP

 

 

以上就是数组就和的函数代码,我们来一句一句的分析。

 

 

首先,我们定义了一个函数,用下面的语句

 

ArraySum PROC

 

然后,我们为了保存esi和ecx的值,将其push进了堆栈中,这样,我们在整个函数结束之后,就可以重新通过pop得到esi和ecx原来的值:

 

         push esi        ; save ESI,ECX

         push ecx

 

然后,因为我们会将我们就得的数组的和一直保存在eax寄存器当中,所以用以下语句将EAX寄存器清零:

 

         mov eax,0     ; set the sum to zero

 

然后,我们增加了一个L1的标号,用于循环,接着我们就开始了循环,看一下代码:

 

L1:

         add eax,[esi] ; add each integer to sum

         add esi,4       ; point to next integer

         loop L1          ; repeat for array size

 

首先,esi寄存器中保存着当前数组的元素的偏移地址,然后通过方括号,可以取得此地址的数组值,将其add到eax中,然后,又将esi这个地址增加4(因为我们这里计算的是32位整数的就和,32位整数,需要4个BYTE,所以,这里我们将esi增加的是4,而不是其他值,这样便得到了下一个数组元素的偏移地址),然后下一句跳回标号L1。

 

说到这里,有人可能会问,那循环如何知道什么时候结束呢?其实在循环的时候,寄存器ECX中保存了循环会执行的次数(这里就是数组元素的个数),看看函数的注释:

 

 

;----------------------------------------------------------------------------

ArraySum PROC

;

;  Calculates the sum of an array of 32-bit integers.

;  Receives : ESI = the  array offset

;                   ECX = number of elements in the array

;  Returns : EAX = sum of the array elements

;----------------------------------------------------------------------------

 

这一句:

 

ECX = number of elements in the array

 

说明了ECX寄存器保留了数组中元素的个数(ECX寄存器保留循环的个数,并且在循环的时候(每执行一次LOOP),会自减1,直至变为0),所以这个其实是需要我们在调用ArraySum 这个函数之前,将数组元素的个数计算出来之后,保留在ECX寄存器中的。

 

到这里,函数的功能就完成了,不过我们还要进行一下收尾工作,看以下的代码:

 

         pop ecx         ; restore ECX,ESI

         pop esi

         ret                 ; sum is in EAX

 

我们需要把ECX和ESI寄存器之前的值赋回去,我们只要弹出ecx和esi就可以了。

 

最后一句ret是所有非主函数都需要带的,用来将 指令指针寄存器ESP 指向函数调用之前的地址,好接着让主函数向下执行。

 

 

然后我们再来看看如何使用这个数组求和函数。

 

.data

array  DWORD 10000h,20000h,30000h,40000h,50000h

theSum DWORD

.code

main PROC

    mov esi , OFFSET array         ; ESI points to array

    mov ecx, LENGTHOF array     ; ECX = array count

    call ArraySum                        ; calculate the sum

    mov theSum , eax                 ; return in EAX

main ENDP

END main

 

在这里,我们看到,主函数确实在执行ArraySum函数之前向esi和ecx寄存器中放入了合适的值^_^。

 

 

另外,我们还可以不使用上面那种容易出错的方法,而使用伪指令 USES 来代替我们进行寄存器值的保存,下面是使用USES修改后的求和代码:

 

ArraySum PROC USES esi ecx

      mov eax , 0

L1:

      add eax , [esi]

      add esi , 4

      loop L1

      ret

ArraySum ENDP

 

编译器将生成以下代码:

 

ArraySum PROC

      push esi

      push ecx

      mov eax , 0

L1:

      add eax , [esi]

      add esi , 4

      loop L1

      pop ecx

      pop esi

      ret

ArraySum ENDP

 

 

 (注意:不能将用于过程的返回值的寄存器进行压栈和弹出,否则其中的值会丢失,例如此例中的EAX)

 

1
0
分享到:
评论

相关推荐

    汇编程序 求数组元素的最大值和最小值

    本篇文章将详细探讨如何使用汇编语言编写程序来找出数组中的最大值和最小值。 首先,我们需要了解汇编语言的基本概念。在汇编语言中,我们使用指令来表示计算机的操作,如加载(LOAD)、存储(STORE)、加法(ADD)...

    digui.rar_emu8086_emu8086数组求和_数组emu8086

    综上所述,使用emu8086处理数组,无论是进行求和还是排序,都需要对8086汇编语言有深入的理解,包括内存管理、循环结构、指针操作以及可能的递归实现。在digui.asm文件中,我们期望看到这样的实现细节。

    汇编语言简单求平均值程序

    ### 汇编语言简单求平均值程序 #### 背景介绍 汇编语言是一种低级编程语言,它直接对应计算机的机器指令集。在本篇内容中,我们将探讨一个简单的汇编语言程序,该程序用于计算一组数值的平均值,并将其精确到小数点...

    汇编语言成绩统计程序

    在汇编语言中,数组的创建和操作可能需要手动管理内存,包括分配、初始化和释放空间。此外,我们还需要记录学生总数,以便进行统计计算。 3. **统计计算**:计算总成绩、平均成绩、优秀人数、良好人数等,涉及基本...

    汇编语言,矩阵相乘课程设计

    汇编语言是通过符号化的指令来表示机器代码,每一条汇编指令通常对应一个特定的机器码。在这个“汇编语言,矩阵相乘课程设计”项目中,我们将探讨如何使用汇编语言实现两个矩阵的乘法操作,这是一种常见的数值计算...

    汇编语言实例

    在实际编写汇编代码时,需要考虑效率和可读性,因为汇编语言往往比高级语言更为复杂且不易阅读。此外,调试汇编程序也是挑战之一,因为错误可能会隐藏在细微的细节中。 这些实例为学习者提供了实践经验,帮助他们更...

    汇编语言-在线第7周2.pdf

    在汇编语言中,循环是程序控制结构的重要组成部分,用于重复执行一段代码直到满足特定条件为止。本篇内容主要讨论了通过计数控制实现的循环,特别是针对数组求和以及寻找最大值的问题。 计数控制循环,顾名思义,是...

    计原实验一 MIPS指令_汇编语言_

    每个`.asm`文件可能对应实验中的一个特定任务,如1-4.asm可能是数组求和的实现,1-6.asm可能是求最大值或最小值的代码,而`实验1 MIPS指令系统与体系结构.pdf`可能是详细的实验指南,涵盖了上述知识点的详细解释和...

    汇编语言学习教程,包含完整教程及各章节代码

    超详细的汇编语言学习教程,适合零基础的同学 一、基础介绍 汇编语言简介 80×86 计算机组织 80×86 的指令系统和寻址方式 ...数组求和 冒泡排序 n 的阶乘 大小写转换 三、例题讲解 单项选择题 填空专题 程序格式专题

    汇编语言 学生成绩统计

    根据给定的汇编语言程序,我们可以总结出以下几个重要的知识点: ...通过以上分析,我们可以看出该汇编语言程序实现了学生成绩的统计功能,包括成绩求和、平均分计算以及按分数段进行成绩分类统计等功能。

    汇编语言程序设计之循环程序

    以题目给出的示例7.1为例,程序需要对两个内存区域DATA1和DATA2中的50对无符号字数据进行求和,并将结果存入SUM数组。这是一个典型的单重循环程序,循环次数为50次。程序通过初始化CX寄存器为50,然后使用`AGAIN`...

    汇编语言程序设计大作业

    【汇编语言程序设计大作业】是一门针对信息安全专业学生的大作业,旨在加深对汇编语言的理解和应用。作业的核心任务是设计一个程序,能够处理一系列学生的考试成绩,包括成绩的合法验证、平均分、最高分、最低分的...

    汇编语言程序设计练习题

    ### 汇编语言程序设计练习题解析 #### 练习题1:输入两个字符,然后按逆序输出。 - **知识点**: - 字符输入/输出:使用INT 21H中断来读取和显示字符。 - 数据交换:通过XCHG或临时变量实现字符数据的交换。 ###...

    汇编语言程序复习题

    1. **基本概念**:汇编语言是面向机器的语言,每条指令对应一个或多个机器码,如`ADD`(加法)、`MOV`(数据移动)等。8086/8088处理器是Intel公司推出的16位微处理器,常用于介绍汇编语言的教学。 2. **文件名称...

    基础汇编程序(1)多位十进制数相加求和显示

    本篇文章将通过一个具体的例子来讲解如何用汇编语言实现多位十进制数相加求和并将其结果显示出来,以此来熟悉基本的汇编语言指令。 #### 实现目标 本次实验的主要目的是学习如何使用汇编语言实现两个多位十进制数...

    汇编语言-在线第7周1.pdf

    在汇编语言中,循环是程序设计中的重要组成部分,它允许重复执行一段代码直到满足特定条件为止。在本文中,我们将深入探讨一种特定的循环指令——`LOOP`指令,以及如何利用它来实现循环控制。 `LOOP`指令是x86架构...

    汇编语言实验DEUBG调试实验

    下面将详细解析此次实验涉及的关键知识点,包括汇编语言的基本概念、实验目标、代码分析及调试方法。 ### 汇编语言基本概念 汇编语言是一种低级程序设计语言,它是面向计算机硬件的语言,其每一条语句几乎都对应着...

    汇编程序-成绩录入,排序,求平均数

    在IT领域,汇编语言是一种低级编程语言,它与机器代码紧密相关,允许程序员对计算机硬件进行直接控制。在这个“汇编程序-成绩录入,排序,求平均数”的项目中,开发者创建了一个简单的程序,用于处理学生的成绩数据。...

Global site tag (gtag.js) - Google Analytics