微软的masm5.0是8位平台的,6.0是16位平台的,还有其他32位平台的。现在编程一般用32位平台,8位和16位都可以在保护模式运行。

最简单的一个程序

assume cs: codesg

codesg segment

start:

mov ax, 4c00h

int 21h

codesg ends

end start

debug一下发现:

-r

AX=0000 BX=0000 CX=0005 DX=0000 SP=0000 BP=0000 SI=0000

DI=0000

DS=0BC0 ES=0BC0 SS=0BD0 CS=0BD0 IP=0000 NV UP EI PL NZ NA PO

NC

0BD0:0000 B8004C MOV AX,4C00

-d 0bd0:0

0BD0:0000 B8 00 4C CD 21 0E 91 46-EB BD 8A D8 F8 EB 05 46

..L.!..F.......F

0BD0:0010 F8 EB 01 F9 8B C1 5A 59-C3 50 51 52 56 53 56 E8

......ZY.PQRVSV.

0BD0:0020 85 FF 2E F6 44 11 01 5E-75 03 E8 01 01 2E C7 06

....D..^u.......

再复杂一点的程序

assume cs: codesg

codesg segment

start: mov ax, 01122h

push ax

mov bx, 3344h

push bx

mov cx, 5566h

push cx

pop ax

pop bx

pop cx

mov ax, 4c00h

int 21h

codesg ends

end start

debug看看两者不同:

-r

AX=0000 BX=0000 CX=0014 DX=0000 SP=0000 BP=0000 SI=0000

DI=0000

DS=0BC0 ES=0BC0 SS=0BD0 CS=0BD0 IP=0000 NV UP EI PL NZ NA PO

NC

0BD0:0000 B82211 MOV AX,1122

-d 0bd0:0

0BD0:0000 B8 22 11 50 BB 44 33 53-B9 66 55 51 58 5B 59 B8

.".P.D3S.fUQX[Y.

0BD0:0010 00 4C CD 21 8B C1 5A 59-C3 50 51 52 56 53 56 E8

.L.!..ZY.PQRVSV.

0BD0:0020 85 FF 2E F6 44 11 01 5E-75 03 E8 01 01 2E C7 06

....D..^u.......

第三行 0BD0:0020是相同的

01122h 3344h 5566h

在程序还没有执行代码里面的指令的时候(还没有运行

t 命令), 这3个是已经存放在内存中的.

看一下 DS指向地址所在的 0BC0 ,里面没有1122 3344

5566

-r

AX=0000 BX=0000 CX=0014 DX=0000 SP=0000 BP=0000 SI=0000

DI=0000

DS=0BC0 ES=0BC0 SS=0BD0 CS=0BD0 IP=0000 NV UP EI PL NZ NA PO

NC

0BD0:0000 B82211 MOV AX,1122

-d 0bc0:0

0BC0:0000 CD 20 FF 9F 00 9A F0 FE-1D F0 4F 03 B2 05 8A 03 .

........O.....

0BC0:0010 B2 05 17 03 B2 05 A1 05-01 01 01 00 02 FF FF FF

................

0BC0:0020 FF FF FF FF FF FF FF FF-FF FF FF FF 5F 0B 4C 01

............_.L.

0BC0:0030 72 0A 14 00 18 00 C0 0B-FF FF FF FF 00 00 00 00

r...............

0BC0:0040 05 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00

................

0BC0:0050 CD 21 CB 00 00 00 00 00-00 00 00 00 00 20 20 20

.!...........

0BC0:0060 20 20 20 20 20 20 20 20-00 00 00 00 00 20 20 20

.....

0BC0:0070 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00

........

所以这些1122 3344

都是放数据段寄存器指向内存的

执行两个t

-t

AX=1122 BX=0000 CX=0014 DX=0000 SP=0000 BP=0000 SI=0000

DI=0000

DS=0BC0 ES=0BC0 SS=0BD0 CS=0BD0 IP=0003 NV UP EI PL NZ NA PO

NC

0BD0:0003 50 PUSH AX

-t

AX=1122 BX=0000 CX=0014 DX=0000 SP=FFFE BP=0000 SI=0000

DI=0000

DS=0BC0 ES=0BC0 SS=0BD0 CS=0BD0 IP=0004 NV UP EI PL NZ NA PO

NC

0BD0:0004 BB4433 MOV BX,3344

-d 0bd0:fffe

0BD0:FFF0 22 11 ".

-d 0bd0:fff0

0BD0:FFF0 00 00 00 00 22 11 00 00-04 00 D0 0B B2 05 22

11 ....".........".

可见 执行完 PUSH AX 以后 SP=FFFE , SS:SP 是 0bd0:fffe ,

也就是 22 11

继续:

-t

AX=1122 BX=3344 CX=0014 DX=0000 SP=FFFE BP=0000 SI=0000

DI=0000

DS=0BC0 ES=0BC0 SS=0BD0 CS=0BD0 IP=0007 NV UP EI PL NZ NA PO

NC

0BD0:0007 53 PUSH BX

-t

AX=1122 BX=3344 CX=0014 DX=0000 SP=FFFC BP=0000 SI=0000

DI=0000

DS=0BC0 ES=0BC0 SS=0BD0 CS=0BD0 IP=0008 NV UP EI PL NZ NA PO

NC

0BD0:0008 B96655 MOV CX,5566

-d 0bd0:fff0

0BD0:FFF0 00 00 22 11 00 00 08 00-D0 0B B2 05 44 33 22 11

..".........D3".

再继续:

-t

AX=1122 BX=3344 CX=5566 DX=0000 SP=FFFC BP=0000 SI=0000

DI=0000

DS=0BC0 ES=0BC0 SS=0BD0 CS=0BD0 IP=000B NV UP EI PL NZ NA PO

NC

0BD0:000B 51 PUSH CX

-t

AX=1122 BX=3344 CX=5566 DX=0000 SP=FFFA BP=0000 SI=0000

DI=0000

DS=0BC0 ES=0BC0 SS=0BD0 CS=0BD0 IP=000C NV UP EI PL NZ NA PO

NC

0BD0:000C 58 POP AX

-d 0bd0:fff0

0BD0:FFF0 22 11 00 00 0C 00 D0 0B-B2 05 66 55 44 33 22 11

".........fUD3".

进栈指令 PUSH 就是这么回事情啦很容易理解.

;将 datasg 段中每个单词改为大写字母

assume cs: codesg, ds: datasg, ss:stacksg

datasg segment

db 'ibm '

db 'dec '

db 'dos '

db 'vax '

datasg ends

stacksg segment ;定义一个段, 用来做栈段, 容量为

16 个字节

dw 0,0,0,0,0,0,0,0

stacksg ends

codesg segment

start: mov ax, stacksg

mov ss, ax

mov sp, 16

mov ax, datasg

mov ds, ax

mov bx, 0

mov cx, 4

s0: push cx ;将外层循环的 cx 值压栈

mov si, 0

mov cx, 3 ; cx 设置为内层循环的次数

s: mov al, [bx + si]

and al, 11011111b

mov [bx + si], al

inc si

loop s

add bx, 16

pop cx ;从栈顶弹出原 cx 的值, 恢复 cx

loop s0 ;外层循环的 loop 指令将 cx 中的计数值减 1

mov ax, 4c00h

int 21h

codesg ends

end start

-r

AX=0000 BX=0000 CX=007E DX=0000 SP=0000 BP=0000 SI=0000

DI=0000

DS=0BC0 ES=0BC0 SS=0BD0 CS=0BD5 IP=0000 NV UP EI PL NZ NA PO

NC

0BD5:0000 B8D40B MOV AX,0BD4

-d 0bd0:0

0BD0:0000 69 62 6D 20 20 20 20 20-20 20 20 20 20 20 20 20 ibm

0BD0:0010 64 65 63 20 20 20 20 20-20 20 20 20 20 20 20 20 dec

0BD0:0020 64 6F 73 20 20 20 20 20-20 20 20 20 20 20 20 20 dos

0BD0:0030 76 61 78 20 20 20 20 20-20 20 20 20 20 20 20 20 vax

......

-d 0bd4:0

0BD4:0000 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00

................

......

ds: datasg

DS(Data Segment):数据段寄存器;

但是这个属于 ds 的 datasg

开辟的内存空间的地址却是 SS(Stack Segment

堆栈段寄存器)指向的地址

0BD4 在 0BD5 前面, 可以看出开辟空间后,

接下去才是 CS(Code Segment代码段寄存器):

;将 datasg 段中每个单词改为大写字母

assume cs: codesg, ds: datasg, ss:stacksg

datasg segment

db 'ibm '

db 'dec '

db 'dos '

db 'vax '

datasg ends

stacksg segment ;定义一个段, 用来做栈段, 容量为

16 个字节

dw 0,0,0,0,0,0,0,0

stacksg ends

codesg segment

start: mov ax, stacksg

mov ss, ax

mov sp, 16 ; ss:sp 指向 stacksg 表的栈顶

mov ax, datasg

mov ds, ax ; ds:bx 指向 datasg 最前面

mov bx, 0

mov cx, 4

s0: push cx ;将外层循环的 cx 值压栈 ss:sp = 04

mov si, 0 ;借用源变址寄存器 si

定位每行要修改的是第几个字母

mov cx, 3 ; cx 设置为内层循环的次数

s: mov al, [bx + si] ;将 ds:[bx + si]临时放进 al

and al, 11011111b ;与的结果是小写改大写 11011111b 写成

16 进制是 DF

mov [bx + si], al ;改了一个字母为大写后再放回去

inc si

loop s ;循环直至 cx = 0

add bx, 16 ;已经修改了1行为大写,换下一行

pop cx ;未pop时, cx 因为执行完上个循环 cx = 0 ,

;从栈顶弹出原 cx 的值, 恢复 cx, cx = 4

loop s0 ;外层循环的 loop 指令将 cx 中的计数值减 1

;因 cx = 4 ,执行 loop s0

这一句的话势必作为计数器的cx自动减1为3

mov ax, 4c00h

int 21h

codesg ends

end start

出栈的结果是

AX=0B4D BX=0000 CX=0000 DX=0000 SP=000E BP=0000 SI=0003

DI=0000

DS=0BD0 ES=0BC0 SS=0BD4 CS=0BD5 IP=0023 NV UP EI PL NZ NA PE

NC

0BD5:0023 83C310 ADD BX,+10

-t

AX=0B4D BX=0010 CX=0000 DX=0000 SP=000E BP=0000 SI=0003

DI=0000

DS=0BD0 ES=0BC0 SS=0BD4 CS=0BD5 IP=0026 NV UP EI PL NZ NA PO

NC

0BD5:0026 59 POP CX

-d 0bd4:000e 000e

0BD4:0000 04 .

;所谓的出栈无非就是把 ss:ps

最外层放的东西赋值给写在pop后面寄存器

;POP CX 的结果是 CX=0004

-t

AX=0B4D BX=0010 CX=0004 DX=0000 SP=0010 BP=0000

SI=0003 DI=0000

DS=0BD0 ES=0BC0 SS=0BD4 CS=0BD5 IP=0027 NV UP EI PL NZ NA PO

NC

0BD5:0027 E2EA LOOP 0013

-d 0bd4:000e 000e

0BD4:0000 B2 .

; loop s0 ;外层循环的 loop 指令将 cx 中的计数值减

1

; ;因 cx = 4 ,执行 loop s0

这一句的话势必作为计数器的cx自动减1为3

-t

AX=0B4D BX=0010 CX=0003 DX=0000 SP=0010 BP=0000

SI=0003 DI=0000

DS=0BD0 ES=0BC0 SS=0BD4 CS=0BD5 IP=0013 NV UP EI PL NZ NA PO

NC

0BD5:0013 51 PUSH CX

汇编自动出栈_汇编自学 (12) 重温进出栈指令PUSH POP 和双循环相关推荐

  1. 汇编自动出栈_汇编学习-入栈和出栈

    栈有两个基本的操作:入栈和出栈.入栈就是将一个新的元素放到栈顶,出栈就是从栈顶取出一个元素.栈顶的元素总是最后入栈,需要出栈时,又最先被从栈中取出.栈的这种操作规则被称为:LIFO(Last In F ...

  2. java集合框架栈_自己实现集合框架(九):栈接口

    这是系列文章,每篇文章末尾均附有源代码地址.目的是通过模拟集合框架的简单实现,从而对常用的数据结构和java集合有个大概的了解.当然实现没有java集合的实现那么复杂,功能也没有那么强大,但是可以通过 ...

  3. 栈顶指针设计和数据进出栈时指针移动的关系

    栈是先进后出的结构体,栈顶指针有两种情况 : 1, 栈顶指针指向的是空的位置 2, 栈顶指针指向栈顶的数据 第一种情况:当栈顶指针指向的是一个空位置.当栈不为空的时候 想出栈时候,系统得知道哪个数据出 ...

  4. 微信小程序页面栈_微信小程序使用页面栈改变上一页面的数据

    微信小程序中如果从一个页面中进入下一个页面,如果下个页面的数据有删除或者增加再返回上一个页面的时候,就会导致页面不刷新(数据加载函数在onload中),从而造成数据不一致的情况.其实在微信小程序中是可 ...

  5. javascript 全栈_什么是JavaScript? 全栈编程语言

    javascript 全栈 JavaScript是一种流行的解释性脚本语言,在2019年初成为开发人员最常学习的语言 . JavaScript是一种开放标准,不受任何单一供应商的控制,具有多种实现方式 ...

  6. 【Android 逆向】x86 汇编 ( push / pop 入栈 / 出栈 指令 | ret / retn 函数调用返回指令 | set 设置目标值指令 )

    文章目录 一.push / pop 入栈 / 出栈 指令 二.ret / retn 函数调用返回指令 三.set 设置目标值指令 总结 一.push / pop 入栈 / 出栈 指令 push / p ...

  7. c语言isempty函数代码,使用C语言实现链栈以及initialize,push,pop,isEmpty,getlength,destory等操作...

    本文使用了链栈,相对于顺序栈,链栈具有通常情况下不会出现栈满的情况 链栈和链表很相似. 由于栈的先进后出特性,栈在很多地方都很适用,比如 括号匹配,算术表达式求职,路径判断(走迷宫游戏)高级点的有函数 ...

  8. arm64入栈出栈_使用 ARM64 汇编实现共享栈式协程

    # 简述 大约在半年以前,我曾经了解过协程的相关实现,也看过腾讯后台开源的协程库`libco`,对其中实现协程相关的汇编有很深的印象(`libco`适配的是 x86 平台).接受了这样的思想,我在自己 ...

  9. 汇编语言中xor指令_汇编各类指令用法及含义分析 - 全文

    什么是汇编语言 汇编语言(assembly language)是一种用于电子计算机.微处理器.微控制器或其他可编程器件的低级语言,亦称为符号语言.在汇编语言中,用助记符(Mnemonics)代替机器指 ...

最新文章

  1. SqlServer 自动化分区方案
  2. Windows2003使用命令行设置共享权限与安全权限心得
  3. 近期工作中使用到的插件总结
  4. 让数字保持在整数范围内
  5. 32位存储字长存储double_1GB多大?1GB与1MB的关系?详细数据存储单位转换来了...
  6. UniWebView 3 使用心得
  7. 把网络图片URL转化为流
  8. 设置模式之UML中的类图及类图之间的关系
  9. 【Unity 资源分享】☀️ | Unity 华丽炫酷特效资源分享!万年魂环拿到手软,让你直达封号斗罗~
  10. android keep倒计时,Android仿Keep运动休息倒计时圆形控件
  11. 烂土豆搭配令牌窃取提权dll劫持搭配令牌窃取提权不带引号服务路径问题提权不安全的服务权限配置提权
  12. C++Primer Excise Ch1
  13. 【Proteus】动态数码管显示
  14. 【人工智能】Google I/O 2023:让 AI 对每个人都更有帮助 Making AI more helpful for everyone
  15. 路由器WiFi密码更改及隐藏操作
  16. java极光短信的集成
  17. 手机软件测试自学乐器,自学乐器不难!——从用好这6款APP开始吧
  18. 手机号码批量导入通讯录php,怎么从电脑上的excel表格的手机号码导入通讯录到华为手机:...
  19. js逆向加密五邑大学教务系统密码AES实现模拟登录(仅供参考)
  20. 使用python计算水仙花数

热门文章

  1. 编程项目构建--点线面体
  2. 在java的实现栈的插入数据_栈之Java实现数据结构
  3. 华为新系统鸿蒙升级时间,好消息确定!鸿蒙之后华为全新系统发布,只期待升级尝鲜...
  4. 服务器声卡图标显示x,电脑声音图标显示红叉【设置模式】
  5. 巧妙关闭iView的Modal框
  6. 来自Trenches的观点:考察Thread-Dumps
  7. 音乐制作需要学计算机编程吗,编程和音乐的10个共同点
  8. 【Proteus仿真】【STM32单片机】玩转TFTLCD彩屏设计
  9. 计算机应用基础答案2010,计算机应用基础2010参考答案.doc
  10. 货物出库管理信息系统