毁掉自己的汇编程序

简介:   下午的上机课,有位同学写的程序死了。她百思不得其解。   我看了几遍程序,没有发现问题。   多次观察后,发现程序修改数据时,由于循环次数错误地设多了,以致于改到了代码段——代码段的指令于是被当作数据改掉了,而此处的数据,当然它仍然还要被当作指令执行,恰好对应了wait指令!于是,程序进入了等待……   那程序到底有没有问题?我看的程序没有问题,但运行的,却是老版本

  下午的上机课,有位同学写的程序死了。她百思不得其解。
  我看了几遍程序,没有发现问题。
  多次观察后,发现程序修改数据时,由于循环次数错误地设多了,以致于改到了代码段——代码段的指令于是被当作数据改掉了,而此处的数据,当然它仍然还要被当作指令执行,恰好对应了wait指令!于是,程序进入了等待……
  那程序到底有没有问题?我看的程序没有问题,但运行的,却是老版本的.exe。开始时,源程序是错误的,她修改后,却没有再编译、接连!唉,这样的错也能犯?难为我当教师的了。麻子不叫麻子,叫什么来着?
  按下这个不表,想给大家展示能毁掉自己的奇葩代码。为简单化,我不再用她当时调试的程序,而是设计一个能说明问题的错误程序,把事情说清楚,大家也见识一下就行了。
  我要编的程序,其任务是:将数据区中的所有数据,变为其2倍并存储在原处。阅读下面的有逻辑错误的程序:

assume cs:codesg,ds:datasg
datasg segment
    dw 1,2,3,4,5,6,7,8
datasg ends

codesg segment
start: mov ax, datasg
       mov ds, ax
       mov si, 0
       mov cx, 16  ;这儿应该是8,修改8个字,但错误地写成16了
    s: mov ax, [si]
       add ax, ax
       mov [si], ax
       add si, 2
       loop s

       mov ax,4c00h
       int 21h
codesg ends
end start

  把连接好的程序用debug装入内存观察:
这里写图片描述
(图1)
  可见,数据从物理地址076A0H处开始,一共同8个字,由1到8;从076B0处始,是代码!图1中,用d命令看到的076B0处的值与用u命令看到的,是一样的值,只不过,前者被当作数据,后者被当作指令。内存中的数据就是那样的,到底是数据还是指令,取决于我们要将它当作什么。
  下面我们执行程序。
  我先揭晓了迷底,这个程序就是循环次数设错了。前8次的循环,完成的是任务中要求的事情,后8次循环,彻底的捣乱。
  用g命令和t命令交替,让循环执行8次:
这里写图片描述
(图2)
  执行8次后,是这样的:
这里写图片描述
(图3)
  注意:由(DS)=076AH, (SI)=0010H,(CS)=076BH,当再执行mov [si], ax指令时,修改的就是代码了!程序在毁掉自己!
  我们将循环再执行3次:
这里写图片描述
(图4)
  再用d命令和u命令观察:
这里写图片描述
(图5)
  快对照图2!看到了吗?076B0H处的mov ax, 076A呢?076B3H处的mov ds, ax呢?现在的代码已经被改的面目全非!
  再用t和g执行两次:
这里写图片描述
(图6)
  江山已经破败到如此境地,无法收拾了!

  好了,毁掉自己的汇编程序演示到此。说点什么。
  这种情况,放在高级语言中很难发生。在操作系统尽责的内存管理下,在各种机制约束下,程序安全地存储、运行。
  然而,汇编语言就这么任性!
  这需要我们这些专业人士要对底层熟悉,有足够的敏感不犯这些错误,当然也要有足够的职业道德,不用这种手段去搞破坏。
  当这种问题就要发生,我们还需要用debug之类的底层调试工具,找出bug,使之曝光于天下!
  自豪吧,小猿们!

目录
相关文章
|
5月前
|
编译器 C语言
【C语言航路外传】一招解决visual studio部分函数不安全问题
【C语言航路外传】一招解决visual studio部分函数不安全问题
48 0
|
25天前
|
开发框架 Java .NET
救命!C程序运行原理的秘密居然被我发现了
救命!C程序运行原理的秘密居然被我发现了
9 0
|
5月前
|
编译器 C语言
【C语言航路外传】输入输出函数及输入缓冲区的那点事
【C语言航路外传】输入输出函数及输入缓冲区的那点事
27 0
|
7月前
|
C语言
写一个简单的背单词c语言程序
写一个简单的背单词c语言程序
53 0
|
11月前
|
Python
一日一技:你的代码是如何被炫技毁掉的
一日一技:你的代码是如何被炫技毁掉的
75 0
|
11月前
|
监控 算法 网络协议
MIPS架构番外篇1-一条小小的除法指令引起的翻车事故
MIPS架构番外篇1-一条小小的除法指令引起的翻车事故
|
存储 自然语言处理 程序员
【维生素C语言】第十八章 - C语言程序环境
程序环境是什么?我们都 "经历" 过,但不曾感知到 "他" 的存在。我们其实在不知不觉中早就已经接触到了程序环境…… 第一次创建了一个文件(test.c),敲下那句 "hello world" 随后保存后点击运行后编译出可执行文件(test.exe)时,其实就已经接触到了 "他" 了。
51 0
【维生素C语言】第十八章 - C语言程序环境
|
人工智能 程序员 编译器
【C语言指针详解-CSAPP数据段解析】1024程序员节 | 汇编语言机械级编程|用代码,改变世界#
【C语言指针详解-CSAPP数据段解析】1024程序员节 | 汇编语言机械级编程|用代码,改变世界#
90 0
【C语言指针详解-CSAPP数据段解析】1024程序员节 | 汇编语言机械级编程|用代码,改变世界#
|
存储
微机原理之指令系统和汇编程序设计
### **8086 CPU的七种寻址方式** 8086 CPU寻址方式 •8086中,CS、DS、ES和SS段寄存器在程序运行过程中分别指向当前的代码段、数据段、附加段和堆栈段。而操作数可能存放在代码段中,也可能存放在数据段、附加段、堆栈段中,还可能存放在8086CPU内部的寄存器中。**存放操作数的内存单元相对于其所在段的段起始地址偏移量称为偏移地址或有效地址EA(Effective Address)。获得操作数所在地址的方法称为寻址方式。**在8086系统中,一般将寻址方式分为两类:一类是寻找操作数的地址;另一类是寻找要执行的下一条指令的地址,即程序寻址。 •MOV DST, SRC
219 0
微机原理之指令系统和汇编程序设计
|
程序员
程序人生 - 程序员们,千万不要接私活!
程序人生 - 程序员们,千万不要接私活!
261 0
程序人生 - 程序员们,千万不要接私活!