8086汇编栈段为何“乱套”了

2024-03-03 05:38
文章标签 汇编 8086 乱套 栈段

本文主要是介绍8086汇编栈段为何“乱套”了,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

带学生在课堂上观察在子程序调用时机器内部发生变化的细节。
  有同学关注到了栈中的“乱套”。
  程序如下:

assume cs:code, ss:stack
stack segmentdb  16 dup (0)
stack ends
code segment
start: mov ax,stackmov ss,axmov sp,16mov ax,1000call s   ;调用子程序mov ax,4c00hint 21hs: add ax,ax     ;子程序开始ret           ;子程序返回
code ends
end start

编译、连接,并在debug中运行后,界面是:
在这里插入图片描述
  容易推算出,此时的栈空间为076A:0到076A:F。
  乱子始于执行MOV SS, AX。并且,本来单步执行一条指令,但MOV SP, 10H没有出现,但,SP的值的确已经变了。
  MOV SP, 10H执行过了——是debug自己干了,没有给程序员单步的机会。这个和中断机制相关(在王爽教材12.11和12.12有详细解释,在此不详述)。
  再往后走,可以看见CALL指令执行过程中,栈是按照我们想到的机制进行。

把程序改一下:

assume cs:code, ss:stack
stack segmentdb  16 dup (0)
stack ends
code segment
start: mov ax,stack;mov ss,ax  ;把这一句加了注释mov sp,16mov ax,1000call s   ;调用子程序mov ax,4c00hint 21hs: add ax,ax     ;子程序开始ret           ;子程序返回
code ends
end start

运行后的界面:
在这里插入图片描述
  可见,引起栈变化的,就是MOV SP, 10H。(这时,没有给SS寄存器赋正确的值,这是危险的,SS保持初进入时的0769H。但为了观察,也就这样捣乱一下看看。)
  再往后走,可以看见CALL指令的执行,是按照我们想到的机制进行。
  -----
  初步结论:栈段的“乱套”,来自于修改SP的值。
  引申解释:修改SP的值时,存在着某种机制使用了栈,从而给栈中留下了一些数据。其实这些数据应该不是随便的乱数据,当知道更多时,可以找出这些数据的之所以来。
  遗留问题的解决:或许可以从中断机制中可以找出一些线索,留待以后再说。

这篇关于8086汇编栈段为何“乱套”了的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/768614

相关文章

笔记整理—内核!启动!—kernel部分(2)从汇编阶段到start_kernel

kernel起始与ENTRY(stext),和uboot一样,都是从汇编阶段开始的,因为对于kernel而言,还没进行栈的维护,所以无法使用c语言。_HEAD定义了后面代码属于段名为.head .text的段。         内核起始部分代码被解压代码调用,前面关于uboot的文章中有提到过(eg:zImage)。uboot启动是无条件的,只要代码的位置对,上电就工作,kern

汇编:嵌入式软件架构学习资源

成为嵌入式软件架构设计师需要掌握多方面的知识,包括嵌入式系统、实时操作系统、硬件接口、软件设计模式等。 以下是一些推荐的博客和网站,可以帮助你深入学习嵌入式软件架构设计: ### 1. **Embedded.com**    - **网址**: [Embedded.com](https://www.embedded.com/)    - **简介**: 这是一个专注于嵌入式系统设计的专业网

GDB 查看汇编

查看汇编 x disassemble

C语言-程序环境 #预处理 #编译 #汇编 #链接 #执行环境

文章目录 前言 一、程序的环境翻译和执行环境 二、翻译环境 (一)、整体把握 (一)、编译 1、预处理(预编译) 2、编译 a、词法分析 b、语法分析 c、语义分析 d、符号汇总 3、汇编 (二)、链接 三、运行环境 总结​​​​​​​ 前言 路漫漫其修远兮,吾将上下而求索; PS:本文参考了《程序员的自我修养》,致敬大佬们! 一、程序的

Linux 技巧汇编

10个重要的Linux ps命令实战 显示所有当前进程 根据用户过滤进程 通过cpu和内存使用来过滤进程 通过进程名和PID过滤 根据线程来过滤进程 树形显示进程 显示安全信息 格式化输出root用户(真实的或有效的UID)创建的进程 使用PS实时监控进程状态 https://linux.cn/article-4743-1.html Python 云服务器应用 | Http

正点原子阿尔法ARM开发板-IMX6ULL(二)——介绍情况以及汇编

文章目录 一、裸机开发(21个)二、嵌入式Linux驱动例程三、汇编3.1 处理器内部数据传输指令3.2 存储器访问指令3.3 压栈和出栈指令3.4 跳转指令3.5 算术运算指令3.6 逻辑运算指令 一、裸机开发(21个) 二、嵌入式Linux驱动例程 三、汇编 我们在进行嵌入式 Linux 开发的时候是绝对要掌握基本的 ARM 汇编,因为 Cortex-A 芯片一

GCC编程过程:预处理-编译-汇编-链接

 在Linux下进行C语言编程,必然要采用GNU GCC来编译C源代码生成可执行程序。 一、GCC快速入门 Gcc指令的一般格式为:Gcc [选项] 要编译的文件 [选项] [目标文件] 其中,目标文件可缺省,Gcc默认生成可执行的文件名为:编译文件.out 我们来看一下经典入门程序"Hello World!" # vi hello.c #include <stdlib.h> #

X86汇编基础

1. mov指令及几种内存寻址方式: 寄存器模式(register mode),以%开头的寄存器标示符 立即数(immediate):是以$开头的数值 直接寻址(direct):直接访问一个指定的内存地址的数据 间接寻址(indirect):将寄存器的值作为一个内存地址来访问内存 变址寻址(displaced):在间接寻址之时改变寄存器的数值 AT&T汇编格式与Intel汇

编译原理项目——C++实现C语言编译器输出为8086级汇编(代码/报告材料)

完整的材料 代码见文章末尾 以下为核心内容和部分结果 项目介绍 一个小型的c语言编译器,实现的功能如下: 可以定义多个变量,并且能初始化。可以支持基本的加减乘除运算。可以支持带括号的多个变量的四则混合运算。可以支持单行注释和多行注释。可以输出%d格式的整数。可以定义int 类型。可以输出字符串。可以输出2位整数可以支持简单的if{}else{}语句。(大于和小于比较条件)以上支持的语法可以混

ARM基础---编程模型---ARM汇编

一、编程模型 1.1.数据和指令集 1.数据 ARM 采用的是32位架构。 ARM 约定:Byte : 8 bits Halfword : 16 bits (2 byte)Word : 32 bits (4 byte)Doubleword 64-bits(8byte)(Cortex-A处理器) 2.指令 ARM 指令集(32-bit)Thumb 指令集(16-bit)//一般用于紧