先看一个简单的汇编程序:
assume cs:code,ss:stack stack segment dw 10 dup('a') stack ends code segment start: mov ax,stack mov ss,ax mov sp,20 mov ax,1 mov cx,4 call s mov ax,4c00h int 21h s: add ax,ax loop s ret code ends end start
自定义一个stack段,然后产生一次方法调用,用ms的debug工具单步调试,可以看到编译后的代码里边s这个标号变成了offset:
-u 0B55:0000 B8530B MOV AX,0B53 0B55:0003 8ED0 MOV SS,AX 0B55:0005 BC1400 MOV SP,0014 0B55:0008 B80100 MOV AX,0001 0B55:000B B90400 MOV CX,0004 0B55:000E E80500 CALL 0016 0B55:0011 B8004C MOV AX,4C00 0B55:0014 CD21 INT 21 0B55:0016 03C0 ADD AX,AX 0B55:0018 E2FC LOOP 0016 0B55:001A C3 RET
call s在编译后对应的指令是:
0B55:000E E80500 CALL 0016
前边表示内存单元,即调试的时候把程序加载到了0b55:0开始的内存区域,而call s对应的机器码在0b55 * 16 + E的地方,E80500表示call s指令编译后的机器码,E8表示call指令,0500是s标号编译后的地址,由于call实际上等同于是call near ptr s,而near编译后是两个字节的值。而这里的5是offset,而不是绝对地址,call 后边的0016是根据call s下一条指令的地址0b55:0011加上这个offset计算出来的,也就是0b55:0016,由于call near ptr s是段内转移,所以段地址不变,即0b55,只显示0011了。
另外,从内存单元的机器码和其对应的汇编指令看,mov ax stack被编译成了:
0B55:0000 B8530B MOV AX,0B53即在0b53:0的位置,应该是我们栈的内存区域(为了更明显起见,我用dw 10 dup('a')初始化的栈内存区):
-d 0b53:0 0B53:0000 61 00 61 00 61 00 61 00-61 00 61 00 61 00 61 00 a.a.a.a.a.a.a.a. 0B53:0010 61 00 61 00 00 00 00 00-00 00 00 00 00 00 00 00 a.a............. 0B53:0020 B8 53 0B 8E D0 BC 14 00-B8 01 00 B9 04 00 E8 0D .S..............从0b53:0开始的16个word,word用两个字节存放,高字节存放在高地址,低字节存放在低地址,用word表示的a,是0061,按地址顺序存放后就成了6100了。
在开始执行前,先看下寄存器的信息:
-r AX=0000 BX=0000 CX=0043 DX=0000 SP=0000 BP=0000 SI=0000 DI=0000 DS=0B43 ES=0B43 SS=0B53 CS=0B55 IP=0000 NV UP EI PL NZ NA PO NC执行前两条条指令后,ss已经指向了0b53:
-t AX=0B53 BX=0000 CX=0043 DX=0000 SP=0000 BP=0000 SI=0000 DI=0000 DS=0B43 ES=0B43 SS=0B53 CS=0B55 IP=0003 NV UP EI PL NZ NA PO NC在执行call s之前,可以看到sp=0014,stack区域的数据却好像被什么改变了:
相关推荐
4. 遇到的问题及解决方法:分享在实现过程中遇到的挑战和如何克服它们,可能是关于中断处理、寄存器使用或其他汇编语言相关的难点。 5. 结果分析:总结项目成果,可能包括最终程序的时间显示效果,以及对汇编语言...
在深入理解C语言的过程调用机制之前...通过这些汇编层面的深入分析,我们可以更好地理解C语言编译后程序的执行流程和内存布局。这不仅对于学习C语言和系统编程是非常有帮助的,也有助于我们编写更高效、更安全的代码。
这些知识点涵盖了ARM汇编语言与C语言、C++之间相互调用的多个层面,包括程序间的接口设计、链接约定的理解和应用,以及在具体编程实践中的注意事项。掌握这些知识点对于进行底层编程、嵌入式系统开发以及混合编程...
《从汇编语言到Windows内核编程》是深入探讨Windows操作系统内部机制的权威之作,尤其适合对计算机系统底层有浓厚兴趣或需要进行系统级开发的读者。这本书将带领读者从最基本的汇编语言出发,逐步过渡到复杂的...
- **函数理解:** 在汇编语言层面理解函数调用机制。 - **输入输出缓冲:** 学习如何在低级别实现输入输出缓冲机制。 - **编译器作用域:** 理解编译器如何处理变量的作用域。 - **多处理概念介绍:** 介绍多核...
### Linux下的系统调用与进程深入解析 #### 系统调用:Linux核心与应用程序间的桥梁 系统调用是Linux操作系统中,用户空间的应用程序与内核之间进行交互的主要方式。它提供了应用程序能够请求内核服务的一系列接口...
在该示例中,我们不仅可以看到基本的除法运算实现过程,还能了解到如何通过汇编语言进行数据存储和调用链接文件等高级操作。 #### 二、关键概念解析 ##### 1. DSP汇编语言简介 DSP汇编语言是为DSP处理器设计的一种...
《Windows环境下32位汇编语言程序设计(第2版)》是一本深入探讨在Windows操作系统下使用32位汇编语言进行程序开发的专业教程。汇编语言是计算机科学的基础,它是一种低级编程语言,直接对应于机器的指令集,使得...
例如,PUSHF(保存标志寄存器到堆栈)和POPF(从堆栈恢复标志寄存器),用于在函数调用前后保存和恢复CPU的状态标志。 四、指令优化技巧 了解和掌握汇编语言指令的优化技巧,对于提高程序的运行效率至关重要。这...
Linux汇编语言AT&T开发指南涵盖了多种编程和系统开发中不可或缺的知识点,特别是对于在Linux环境下开发与底层硬件交互的程序。本指南详细介绍了AT&T汇编语法和指令的使用方法,下面将基于提供的内容点,逐一详细讲解...
汇编语言的学习不仅要求对基本概念有深入的理解,还要求掌握具体的指令集和数据表示方法。通过实践编写简单的汇编语言程序,可以帮助加深对这些概念的理解,并熟悉8086处理器的工作机制。此外,堆栈管理和存储器分段...
综上所述,Intel汇编架构分析涵盖了汇编语言的基本概念、寻址模式、寄存器使用、指令流水线、程序优化以及操作系统层面的机制。理解这些知识点对于深入理解计算机系统的工作原理和编写高性能代码至关重要。
标题与描述强调了汇编语言复习的关键点,涵盖了计算机原理、数与指令的理解、存储器寻址、堆栈操作、指令集以及程序框架等多个方面。下面是对这些知识点的详细解析: ### 一、程序员眼中的计算机 #### 计算机原理...
汇编语言是计算机硬件层面的低级编程语言,它直接对应于机器指令,对理解计算机工作原理和优化程序性能至关重要。这本书详细介绍了IBM PC架构下的汇编语言知识,适合初学者和有经验的程序员进一步提升技能。 在学习...
学习ARM汇编,不仅需要了解每条指令的语法和功能,还需要理解其在硬件层面的执行过程,比如寄存器的使用和流水线机制。 在实际调试过程中,我们可能遇到如下的场景:当C代码中的函数运行异常时,可以通过反汇编查看...
本书首先从基础的汇编语言语法讲起,包括寄存器的使用、指令系统以及基本的数据类型。然后,它将带领读者进入Win32汇编的世界,讲解如何编写与Windows操作系统交互的程序,如创建窗口、处理消息、内存管理等。书中会...
虽然学习汇编语言对于初学者来说可能会觉得难度较大,但只要掌握正确的学习方法,理解其基本原理和结构,你会发现其实汇编语言的学习也可以变得相对轻松。 **汇编语言的特点** 1. **直接性**:汇编语言的指令直接...
机器码与汇编语言是计算机科学中的两个基本概念,它们都是与硬件紧密相关的编程语言形式。机器码,也称为机器语言,是计算机硬件能够直接理解和执行的唯一指令集,由二进制数字组成。而汇编语言则是一种介于机器码和...