分享

MOVSB﹑MOVSW?和?REP?指令

 大饼小姜 2012-01-13

MOVSB﹑MOVSW 和 REP 指令

先说搬移字串。搬移字串指令有两种,分別是 MOVSB 和 MOVSW,先说 MOVSB。MOVSB 的英文是 move string byte,意思是搬移一个字节,它是把 DS:SI 所指位址的一个位元组搬移到 ES:DI 所指的位址上,搬移后原來的內容不变,但是原来 ES:DI 所指的內容会被覆蓋而且在搬移之后 SI 和 DI 会自动地址向下一个要搬移的位址。

一般而言,通常程序设计师只搬一个字节,通常都会重复很多次,如果要重复的话,就得把重复次数先存储在 CX 寄存器,并在 MOVSB 之前加上 REP 指令。

下面演示一下用 DEBUG 来观察 REP MOVSB 执行情形(网友小木偶的演示程序):

C:\WINDOWS>debug [Enter] 
-a [Enter] 
1C6C:0100 mov cx,10 [Enter]
1C6C:0103 mov si,200 [Enter] 
1C6C:0106 mov di,300 [Enter] 
1C6C:0109 rep movsb [Enter] 
1C6C:010B [Enter] 
-a 200 [Enter] 
1C6C:0200 db "I learn assembly" [Enter] 
1C6C:0210 [Enter] 

上面的程式片段是把位于 1C6C:0200 的『I learn assembly』字串移搬到 1C6C:0300 处,此字串共 16 个字元,所以 CX 存入 10H。现在來追踪看看。

-t [Enter] 
AX=0000 BX=0000 CX=0010 DX=0000 SP=FFEE BP=0000 SI=0200 DI=0000 
DS=1C6C ES=1C6C SS=1C6C CS=1C6C IP=0106 NV UP EI PL NZ NA PO NC 
1C6C:0103 BE0002 MOV SI,0200 
-t [Enter] 
AX=0000 BX=0000 CX=0010 DX=0000 SP=FFEE BP=0000 SI=0200 DI=0000 
DS=1C6C ES=1C6C SS=1C6C CS=1C6C IP=0106 NV UP EI PL NZ NA PO NC 
1C6C:0106 BF0003 MOV DI,0300 
-t [Enter] 
AX=0000 BX=0000 CX=0010 DX=0000 SP=FFEE BP=0000 SI=0200 DI=0300 
DS=1C6C ES=1C6C SS=1C6C CS=1C6C IP=0109 NV UP EI PL NZ NA PO NC 
1C6C:0109 F3 REPZ 
1C6C:010A A4 MOVSB 
-d 300 L10 [Enter] 

在还未搬移之前,先看看 1C6C:0300 处的內容,再追踪。

1C6C:0300 E8 A3 F6 74 08 49 46 FE-06 D7 DC EB EF E8 C3 F9 ...t.IF......... 
-t [Enter] 
AX=0000 BX=0000 CX=000F DX=0000 SP=FFEE BP=0000 SI=0201 DI=0301 
DS=1C6C ES=1C6C SS=1C6C CS=1C6C IP=0109 NV UP EI PL NZ NA PO NC 
1C6C:0109 F3 REPZ 
1C6C:010A A4 MOVSB 
-d 300 L10 [Enter] 
1C6C:0300 49 A3 F6 74 08 49 46 FE-06 D7 DC EB EF E8 C3 F9 I..t.IF.........

在搬移一次之后,再看看 1C6C:0300 处的內容,发现上面已经和原來不一样了 (红色部份)。这是因为 movsb 已经把第零个字节搬到 1C6C:0300 处,而覆蓋了原來的內容。而 CX 也減少一,SI﹑DI 也各增加一而指向下一个位址。好!再追踪看看。

-t [Enter] 
AX=0000 BX=0000 CX=000E DX=0000 SP=FFEE BP=0000 SI=0202 DI=0302 
DS=1C6C ES=1C6C SS=1C6C CS=1C6C IP=0109 NV UP EI PL NZ NA PO NC 
1C6C:0109 F3 REPZ 
1C6C:010A A4 MOVSB

您有沒有发现,在搬移完之前,IP 都指向 REP MOVSB 指令 ( 即 REP MOVSB 所在位址 )。要追踪这么多次,太麻烦了,干脆直接执行到搬移字串到结束。

-g 10b [Enter] 
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0210 DI=0310 
DS=1C6C ES=1C6C SS=1C6C CS=1C6C IP=010B NV UP EI PL NZ NA PO NC 
1C6C:010B 06 PUSH ES 
-d 200 L10 [Enter] 
1C6C:0200 49 20 6C 65 61 72 6E 20-61 73 73 65 6D 62 6C 79 I learn assembly 
-d 300 L 10 [Enter] 
1C6C:0300 49 20 6C 65 61 72 6E 20-61 73 73 65 6D 62 6C 79 I learn assembly

搬移结束后,1C6C:0200 和 1C6C:0300 处的內容均相同,所以 MOVSB 事实上是把原來字串复制到要搬移之处,而原字串是原封不动的。

MOVSW 的作用方式都和 MOVSB 相同,所不同的是 MOVSW 每次搬移一个字,所以每次搬运完 SI﹑DI 會增加 2,而 CX 仍然減少一。

    在此,对网友小木偶提供如此精辟的文章,深表谢意!
 
附上Windows Debug的使用介绍:
 
windows中debug的妙用
DEBUG在每个人的机器里都会有,只是很多人对它都很陌生,不要小看它,对你的破解会很有帮助的。如你掌握了它的用法,对你的日常使用及维护工作会带来很大的方便,下面介绍一些它的基本指令用法:
指令 格式 功能             备注
A  A  [记忆体位址]         组译汇编语言指令 A 100
C  C  [区段1] [区段范围] [区段2]  将两块内存作比较 C 100 L20 200
D  D  [记忆体拉址]         显示记忆体的内容 D 100
E  E  [记忆体位址]         编辑记忆体资料 E 100
F  F  [指定区段范围]        填充指定内存区块内容 F 100 L10 90
G  G  [区段:区址]         带有任选断点执行 G 100
H  H  [运算子] [运算子]      十六进制加减运算 H 44 33
I  I  [端口]            读/显示输入字节
L  L  [记忆位址]或[磁碟,磁轨,磁区] 装入文件或磁区 L 100 2 1 2
M  M  [区段范围] [记忆体位址]   传送内存区块 M 100 L10 110
N  N  [档案名称]          定义文件及参量 N bb.com
O  O  [端口位址]          输出字节到端口
P  P  [区段:区址]         在下一指令上停止 P 2
Q  Q  退出 DEBUG 界面       Q
R  R  [寄存器]           显示修改寄存器/标志 R AX
S  S  [记忆区段范围]        对字符进行检索 S 100 L70 ’j’
T  T  [=记忆区段]或[数值范围]   单步追踪 T
U  U  [记忆位址]          对指令进行反汇编 U 100
W  W  [记忆区段]或[指定范围]    写入文件或磁盘扇区 W 100 0 1 1
下面对一些常用指令进行详细剖析:

A (Assemble)汇编指令
1、输入汇编语句被汇编到内存的指定区段,此区段在开始时用 A address 指定。
2、所有语句输入完成后,按 ENTER 键返回。
3、完成输入后,可以用 U 命令观看它的机械码。

D (Dump)显示命令
1、从指定的地址开始显示内容,如果没有指定地址,则从前一个D命令继续显示。
2、如果没指定地址并是第一次,则从 DS:100 处开始显示。

G (Go)转移命令
1、执行正在调试的程序,当执行到指定的地址时停止,并显示寄存器樗和下一条要
执行的命令。
2、G [=address]用于执行正在调试没有断点的程式。
3、程序运行结束,DEBUG 显示“Porgram terminated normally”。

R (Register)寄存器命令
1、显示一个寄存器的十六进制内容,并可根据需要改变它们。
2、显示8个字母的状态标志,并可根据需要更改它们之中的任一个或全部。

U (Unassemble)反汇编命令
1、对指令进行反汇编,它们的地址和十六进制以类似于汇编语言的语句一起显示出
来。
2、单独用 U 命令从 CS:100 处开始反汇编。
3、U命令默认段地址包含 CS 寄存器中。



DEBUG 技巧应用

1、用 DEBUG 对子目录加密
DOS在管理文件目录时,用 32 个字节来保存根目录和子目录的信息。对子目录而言
0-10 字节为子目录域,第 11 字节为属性。我们只要将子目录属性字节的值从 10H
改为 13H 时,子目录即具有拒绝 DIR、TREE 等命令的性能。

例如:

对 A 盘的 SUBDIK 子目录进行加密:

C:\>DEBUG
-L 100 0 5 7 (将 A 盘中目录读入内存)
-S 100 FFF “SUBDIK“ (搜索子目录)
-38EB:07c0 (搜索到的子目录地址)
-E 07CB (07C)+0B=07CB(为属性字节位址)
38EB:07CB 10.13 (修改完成)
-W 100 0 5 7 (目录写回A盘中)
-Q (退出)

2、解除 BIOS 密码

C:\>DEBUG
-O 70 10
-O 71 11
重新启动,BIOS 密码已被攻破。

3、冷启动实现

C:\>DEBUG RESET.COM
-A 100
JMP FFFF:0000
INT 20
-RCX
00007
-W
-Q

4、热启动实现

C:\DEBUG BOOT.COM
-A 0100
MOV AX,0040
MOV DS,AX
MOV AX,1234
MOV SI,0072
MOV [SI],AX
JMP FFFF:0
INT 20
-RCX
0014
-W
-Q
来自: http://hi.baidu.com/%B9%ED%C8%CB%CD%F5/blog/item/acb9420fc59ca4236159f300.html

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多