编写调试跟踪多段程序
一个小窍门
刚才希望截取 Debug 操作的过程文字,结果内容过长,无法 copy 文件。
试着Debug输出内容重向到一个文本文件内,好是好,只是生成了临时文件。
想了想发现一个好玩的办法,不生成临时文件,直接将操作过程管道输出到剪辑板内,然后我往论坛一粘就行了~:)
不过,所输出的内容是不会显示到屏幕上的。但是用熟了也用着显示什么,知道自己键入的是什么应该出现些什么就行了。
debug p123.exe|clip
下面源代码编译后调试跟踪过程
assume cs:code,ds:data,ss:stack
data segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
data ends
stack segment
dw 0,0,0,0,0,0,0,0
stack ends
code segment
start: mov ax,stack
mov ss,ax
mov ax,data
mov ds,ax
push ds:
push ds:
pop ds:
pop ds:
mov ax,4c00h
int 21h
code ends
end start
试调上面编译过的源代码
-r
AX=0000 BX=0000 CX=003F DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0B39 ES=0B39 SS=0B49 CS=0B4B IP=0000 NV UP EI PL NZ NA PO NC
0B4B:0000 B84A0B MOV AX,0B4A
-u
0B4B:0000 B84A0B MOV AX,0B4A
0B4B:0003 8ED0 MOV SS,AX
0B4B:0005 B8490B MOV AX,0B49
0B4B:0008 8ED8 MOV DS,AX
0B4B:000A FF360000 PUSH
0B4B:000E FF360200 PUSH
0B4B:0012 8F060200 POP
0B4B:0016 8F060000 POP
0B4B:001A B8004C MOV AX,4C00
0B4B:001D CD21 INT 21
0B4B:001F 8B87BE22 MOV AX,
-d cs:0
0B4B:0000 B8 4A 0B 8E D0 B8 49 0B-8E D8 FF 36 00 00 FF 36 .J....I....6...6
0B4B:0010 02 00 8F 06 02 00 8F 06-00 00 B8 00 4C CD 21 8B ............L.!.
0B4B:0020 87 BE 22 0B 87 C0 22 74-E1 8B 9E FE FE D1 E3 D1 .."..."t........
0B4B:0030 E3 8B 87 BE 22 8B 97 C0-22 89 86 FA FE 89 96 FC ...."...".......
0B4B:0040 FE C4 9E FA FE 26 8A 47-0C 2A E4 40 50 8B C3 05 .....&.G.*.@P...
0B4B:0050 0C 00 52 50 E8 19 46 83-C4 04 50 8D 86 00 FF 50 ..RP..F...P....P
0B4B:0060 E8 6F 70 83 C4 06 B8 CD-05 50 8D 86 00 FF 50 E8 .op......P....P.
0B4B:0070 CA 0C 83 C4 04 B8 FF FF-50 8D 86 00 FF 50 8D 46 ........P....P.F
-d ss:0
0B49:0000 23 01 56 04 89 07 BC 0A-EF 0D ED 0F BA 0C 87 09 #.V.............
0B49:0010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0B49:0020 B8 4A 0B 8E D0 B8 49 0B-8E D8 FF 36 00 00 FF 36 .J....I....6...6
0B49:0030 02 00 8F 06 02 00 8F 06-00 00 B8 00 4C CD 21 8B ............L.!.
0B49:0040 87 BE 22 0B 87 C0 22 74-E1 8B 9E FE FE D1 E3 D1 .."..."t........
0B49:0050 E3 8B 87 BE 22 8B 97 C0-22 89 86 FA FE 89 96 FC ...."...".......
0B49:0060 FE C4 9E FA FE 26 8A 47-0C 2A E4 40 50 8B C3 05 .....&.G.*.@P...
0B49:0070 0C 00 52 50 E8 19 46 83-C4 04 50 8D 86 00 FF 50 ..RP..F...P....P
-d ds:0
0B39:0000 CD 20 FF 9F 00 9A F0 FE-1D F0 4F 03 59 05 8A 03 . ........O.Y...
0B39:0010 59 05 17 03 59 05 48 05-01 03 01 00 02 FF FF FF Y...Y.H.........
0B39:0020 FF FF FF FF FF FF FF FF-FF FF FF FF 06 0B 4C 01 ..............L.
0B39:0030 19 0A 14 00 18 00 39 0B-FF FF FF FF 00 00 00 00 ......9.........
0B39:0040 05 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0B39:0050 CD 21 CB 00 00 00 00 00-00 00 00 00 00 20 20 20 .!...........
0B39:0060 20 20 20 20 20 20 20 20-00 00 00 00 00 20 20 20 .....
0B39:0070 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00 ........
-q
代码装入执行前与执行改变栈地址之后的数据对比
-R
AX=0000 BX=0000 CX=003F DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0B39 ES=0B39 SS=0B49 CS=0B4B IP=0000 NV UP EI PL NZ NA PO NC
0B4B:0000 B84A0B MOV AX,0B4A
-T
AX=0B4A BX=0000 CX=003F DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0B39 ES=0B39 SS=0B49 CS=0B4B IP=0003 NV UP EI PL NZ NA PO NC
0B4B:0003 8ED0 MOV SS,AX
-T
AX=0B49 BX=0000 CX=003F DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0B39 ES=0B39 SS=0B4A CS=0B4B IP=0008 NV UP EI PL NZ NA PO NC
0B4B:0008 8ED8 MOV DS,AX
-D SS:0
0B4A:0000 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0B4A:0010 B8 4A 0B 8E D0 B8 49 0B-8E D8 FF 36 00 00 FF 36 .J....I....6...6
0B4A:0020 02 00 8F 06 02 00 8F 06-00 00 B8 00 4C CD 21 8B ............L.!.
0B4A:0030 87 BE 22 0B 87 C0 22 74-E1 8B 9E FE FE D1 E3 D1 .."..."t........
0B4A:0040 E3 8B 87 BE 22 8B 97 C0-22 89 86 FA FE 89 96 FC ...."...".......
0B4A:0050 FE C4 9E FA FE 26 8A 47-0C 2A E4 40 50 8B C3 05 .....&.G.*.@P...
0B4A:0060 0C 00 52 50 E8 19 46 83-C4 04 50 8D 86 00 FF 50 ..RP..F...P....P
0B4A:0070 E8 6F 70 83 C4 06 B8 CD-05 50 8D 86 00 FF 50 E8 .op......P....P.
-D 0B49:0
0B49:0000 23 01 56 04 89 07 BC 0A-EF 0D ED 0F BA 0C 87 09 #.V.............
0B49:0010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0B49:0020 B8 4A 0B 8E D0 B8 49 0B-8E D8 FF 36 00 00 FF 36 .J....I....6...6
0B49:0030 02 00 8F 06 02 00 8F 06-00 00 B8 00 4C CD 21 8B ............L.!.
0B49:0040 87 BE 22 0B 87 C0 22 74-E1 8B 9E FE FE D1 E3 D1 .."..."t........
0B49:0050 E3 8B 87 BE 22 8B 97 C0-22 89 86 FA FE 89 96 FC ...."...".......
0B49:0060 FE C4 9E FA FE 26 8A 47-0C 2A E4 40 50 8B C3 05 .....&.G.*.@P...
0B49:0070 0C 00 52 50 E8 19 46 83-C4 04 50 8D 86 00 FF 50 ..RP..F...P....P
上面是代码装入执行前和改变栈ds的对比,根据上面对比再对比整个代码使用内存的变化。
C:\Masm50>debug p123.exe
-r
AX=0000 BX=0000 CX=003F DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0B39 ES=0B39 SS=0B49 CS=0B4B IP=0000 NV UP EI PL NZ NA PO NC
0B4B:0000 B84A0B MOV AX,0B4A
-d ss:0
0B49:0000 23 01 56 04 89 07 BC 0A-EF 0D ED 0F BA 0C 87 09 #.V.............
0B49:0010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0B49:0020 B8 4A 0B 8E D0 B8 49 0B-8E D8 FF 36 00 00 FF 36 .J....I....6...6
0B49:0030 02 00 8F 06 02 00 8F 06-00 00 B8 00 4C CD 21 C7 ............L.!.
0B49:0040 02 75 48 89 3E E6 99 FF-06 E6 99 C6 06 E8 99 FF .uH.>...........
0B49:0050 C6 06 E9 99 00 E8 99 00-AC E8 29 E2 74 38 3C 0D ..........).t8<.
0B49:0060 74 34 3A 06 B6 96 74 2E-3A C3 74 2A 3C 3A 74 03 t4:...t.:.t*<:t.
0B49:0070 E9 5F FF 80 3E A4 98 02-75 05 E8 74 00 EB D9 46 ._..>...u..t...F
红色标注为 ss 栈段在代码执行前未重新分配时的状态,ss 基地址批向数据在源代码中的定义:
data segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
data ends
而紧跟着它后面的数据 00 00 ……则是为栈安排存储区,它在代码中是这样定义的
stack segment
dw 0,0,0,0,0,0,0,0
stack ends
上面的定义这才是应该为栈分配的空间。
而在这一片 “内存区域” 的后面才是代码入口 ( end start ),cs段地址为:0B4BH
执行前:
|______PSP____|____ss=0b49=8个dw定义的字数据___后8个字00为栈分配___共32字节__|__代码段: cs=0b4b__|
执行后(只执行 为ss栈赋值后),则变化如下:
其 ss=B4A0 ,被定义到了原来的栈与代码段之间了(即向下移了16个字节),
由原来装入时的 SS=0B49 向下移了 16字节。
变为: SS=B4A0。
那么 SS=B4A0 它将指向哪里?见上面反汇编分析,其指向了 dw 0,0,0……在源代码中所定义的栈区。
这是为了方便压栈用。
分析:
) CPU执行程序,程序返回前,data 段中的数据为多少?
-d ds:0
0B49:0000 23 01 56 04 89 07 BC 0A-EF 0D ED 0F BA 0C 87 09
) CPU执行程序,程序返回前,CS=? SS=? DS=?
CS=0B4B SS=0B4A DS=0B49
) 设程序加载后,code段的段地址为X,则data段的段地址为?
stack段的段地址为?
stack段的段地址为: stack=(cs)*16+0B-32B
data段的段地址为: data=(cs)*16+0B-32B - 100H
编译下面代码,用Debug加载、跟踪、调试……
assume cs:code,ds:data,ss:stack
data segment
dw 0123h,0456h
data ends
stack segment
dw 0,0
stack ends
code segment
start: mov ax,stack
mov ss,ax
mov sp,16
mov ax,data
mov ds,ax
push ds:
push ds:
pop ds:
pop ds:
mov ax,4c00h
int 21h
code ends
end start
) CPU执行程序,程序返回前,data段中的数据为多少?
DS = 0B49
DS = 23 01 56 04
) CPU执行程序,程序返回前, CS、SS、DS都是多少?
DS=0B49 SS=0B4A CS=0B4B
) 设程序加载后,code段的段地址为X,则data段的段地址为?
stack段的段地址为?
stack段的段地址为: ( (X)*16 - 32B) / 16
data 段的段地址为: ( (X)*16 - 32B - 256B) ) / 16
) 对于如下定义的段:
name segment
...
name ends
如果段中的数据占N个字节,则程序加载后,该段实际占有空间为?
答:如果 N < FH ,则实际占用 FH 字节。
简单总结:
(到这里,发现一个例子反复的跟踪和对比源代码被编译并反汇编后的“样子”是绝对值得的,直到脑子里已经形成视图为止。)
(每一个基础如果不打好,就向下走,会学得非常快,但越向后学难度越大、难以逾越的障碍就会越多,能力难以再提高。)
(汇编离不开Debug等调试工具,没了这些工具寸步难行。汇编学机器原理,Debug了解真象。)
将下面的程序编译连接,则Debug加载、跟踪……
assume cs:code,ds:data,ss:stack
code segment
start: mov ax,stack
mov ss,ax
mov sp,16
mov ax,data
mov ds,ax
push ds:
push ds:
pop ds:
pop ds:
mov ax,4c00h
int 21h
code ends
data segment
dw 0123h,0456h
data ends
stack segment
dw 0,0
stack ends
end start
分析:
{PSP}{代码}{数据}{栈}
) CPU执行程序,程序返回前,data段中的数据为多少?
DS=0B4C
0B4C:0000 23 01 56 04
) CPU执行程序,程序返回前,CS=? SS=? DS=?
SS=0B4D CS=0B49 DS=0B4C
) 设程序加载后,code段的段地址为X,则data段的段地址为?
stack段的段地址为?
因为 code 段之前没 stack、data 等数据,只有 psp所占用的256B。
所以 data 段地址为: ((CS)*16 - 256B )/ 16
公式写得不太标准。因为文件一被装入,data段自然指向PSP,而stack与data段都在code段后面,
所以code段地址(CS)向回移255B就是PSP。
CX=44H 即:寄存器代码长度为:68 B
实际手工数代码长度为:34 B
则 68B - 34B = 34 B 则视图如下:{有效代码占34B+补满F}{data+补满到F + stack实际占用}
(上面只是视图,不是真正计算方法)
(因为代码结束后的空余空间在F以前是不再用了,为了整除方便)
(所以,再有数据,如栈和数据段的超始地址都是可以将来被16整除的地址,这是最重要的一点)
即: CX代段总长度 - (DATA: dw 0123h,0456h 独占的16倍数的起始行 = 16字节) == DATA段基地址
(CX=68B)-(DATA: 16B)-(最后的stack所真实占用的4B)= 48B(CS段的偏移量)
(CS=0B49H)+48B =0B4CH (这是求出的段地址)
* 现在我们求出了已知CS地址,所以DATA段的地址为: 0B4CH
那么假如 CS=X ,则DATA段地址为: ((x)*16+48B)/16
* 既然已知DATA段地址了,那么STACK只不过是它向下的一个F篇移量,则STACK= (((x)*16+48B)/16)+16B
下面是一些求得如下公式的推理验证。
-d ss:0
0B49:0000 B8 4D 0B 8E D0 BC 10 00-B8 4C 0B 8E D8 FF 36 00
0B49:0010 00 FF 36 02 00 8F 06 02-00 8F 06 00 00 B8 00 4C
0B49:0020 CD 21 00 00 00 00 00 00-00 00 00 00 00 00 00 00
(上面 CD 21 就是代码结束了)
(下面 23 01 56 04 是 dw 0123H,0456H 所定义的数据。)
0B49:0030 23 01 56 04 00 00 00 00-00 00 00 00 00 00 00 00
(下面 00 00 00 是 stack 段在源代码中 dw 0,0 定义的栈空间)
(它们的特点:都是新起一行:)
0B49:0040 00 00 00 00 87 C0 22 74-E1 8B 9E FE FE D1 E3 D1
0B49:0050 E3 8B 87 BE 22 8B 97 C0-22 89 86 FA FE 89 96 FC
0B49:0060 FE C4 9E FA FE 26 8A 47-0C 2A E4 40 50 8B C3 05
0B49:0070 0C 00 52 50 E8 19 46 83-C4 04 50 8D 86 00 FF 50
(它们为什么都要新起一行来存有被定义的新数据?)
(个人理解:)
(这是带有偏移量的数据,如果计算为无偏移量物理地址为:0B4E:1)
(当 MOV AX,0B4E:1 显然无法赋值)
(但 MOV AX,B4E1 表面上看上去是物理地址,但它不是相对段地址,所以更是出错)
(所以,偏移量只要的后面有0,方便段的物理地址(段)*16+偏移量,它的物理地址低位是0,方便再转为无偏移量
的段地址)
-d 0b4d:11
0B4D:0010 00 15 00 49 0B 59 05-56 04 23 01 FE 89 96 FC
0B4D:0020 FE C4 9E FA FE 26 8A 47-0C 2A E4 40 50 8B C3 05
0B4D:0030 0C 00 52 50 E8 19 46 83-C4 04 50 8D 86 00 FF 50
0B4D:0040 E8 6F 70 83 C4 06 B8 CD-05 50 8D 86 00 FF 50 E8
0B4D:0050 CA 0C 83 C4 04 B8 FF FF-50 8D 86 00 FF 50 8D 46
0B4D:0060 80 50 E8 4D FA 83 C4 06-0A C0 75 03 E9 7B FF 5E
0B4D:0070 8B E5 5D C3 83 3E 56 07-20 72 0A B8 1C 04 50 E8
0B4D:0080 62 44 83 C4 02 B8 FF FF-50 B8 05 00 50 8D 86 7A
0B4D:0090 FE
-d 0b4e:1
0B4E:0000 00 15 00 49 0B 59 05-56 04 23 01 FE 89 96 FC
0B4E:0010 FE C4 9E FA FE 26 8A 47-0C 2A E4 40 50 8B C3 05
0B4E:0020 0C 00 52 50 E8 19 46 83-C4 04 50 8D 86 00 FF 50
0B4E:0030 E8 6F 70 83 C4 06 B8 CD-05 50 8D 86 00 FF 50 E8
0B4E:0040 CA 0C 83 C4 04 B8 FF FF-50 8D 86 00 FF 50 8D 46
0B4E:0050 80 50 E8 4D FA 83 C4 06-0A C0 75 03 E9 7B FF 5E
0B4E:0060 8B E5 5D C3 83 3E 56 07-20 72 0A B8 1C 04 50 E8
0B4E:0070 62 44 83 C4 02 B8 FF FF-50 B8 05 00 50 8D 86 7A
0B4E:0080 FE
经过分析,反汇编代码 CD 21 (代码结束了)之后是 00 00 ……
因为刚才分析出必须是(段)*16+偏移量以后,其低位必须有0……
这样形容:就是当段地址*16+偏移量的物地址必须能被16整除才可以。
简单总结:
上面的计算方法并不难,写了这么多笔记是为了推出它们的规律和都是为什么。背一个公式有记记力就行了,那么没有公式的时候怎么办?只能推出解决办法。要想找到解决办法就必须从源代码与反汇编的真实代码之间找到它们的规律,
要找出规律就得用基础知识反复的验算。验算过程中就会发现很多不解的内容,如:为什么要空出一部分空间不用?为什么要新起一行才可以?这些书上没有,怎么办?一遍一遍推,一遍遍算,就会发现很多内容全是基础知识的扩充。
程序的入口地址分析
code segment
start: mov ax,stack ………………
………………
code ends
end start
如果没有在源代码中标出程序入口标置会怎么样?什么样的源代码未标置程序入口就不会运行?
分析如下:
assume cs:code,ds:data,ss:stack
data segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
data ends
stack segment
dw 0,0,0,0,0,0,0,0
stack ends
code segment
start: mov ax,stack
mov ss,ax
mov ax,data
mov ds,ax
push ds:
push ds:
pop ds:
pop ds:
mov ax,4c00h
int 21h
code ends
end
编译后的可执行文件,代码入口就是源代码中按顺序放的数据,哈哈……无法运行~:)
从这里就可以看到 Start 与 end Start 的重要性了,它指出了代码结束与代码入口地址。不过start可以随便启名:)
C:\Masm50>debug aaa.exe
-r
AX=0000 BX=0000 CX=003F DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0B3B ES=0B3B SS=0B4B CS=0B4B IP=0000 NV UP EI PL NZ NA PO NC
0B4B:0000 2301 AND AX, DS:0000=20CD
-u
0B4B:0000 2301 AND AX,
0B4B:0002 56 PUSH SI
0B4B:0003 0489 ADD AL,89
0B4B:0005 07 POP ES
0B4B:0006 BC0AEF MOV SP,EF0A
0B4B:0009 0DED0F OR AX,0FED
0B4B:000C BA0C87 MOV DX,870C
0B4B:000F 0900 OR ,AX
0B4B:0011 0000 ADD ,AL
0B4B:0013 0000 ADD ,AL
0B4B:0015 0000 ADD ,AL
0B4B:0017 0000 ADD ,AL
0B4B:0019 0000 ADD ,AL
0B4B:001B 0000 ADD ,AL
0B4B:001D 0000 ADD ,AL
0B4B:001F 00B84C0B ADD ,BH
) 将 A 段和 B 段中的数据依次相加,将结果 C 段中。
assume cs:code
a segment
db 1,2,3,4,5,6,7,8
a ends
b segment
db 1,2,3,4,5,6,7,8
b ends
c segment
db 0,0,0,0,0,0,0,0
c ends
code segment
start: mov ax,a ; A 段
mov ds,ax
mov dx,b ; B 段
mov es,dx
mov bx,c ; C 段
mov ss,bx
mov bx,0 ; 清零
mov cx,8
s: mov al,ds: ; 把 A 段数据送入 AL
add al,es: ; 将 A 段数据与 B 段偏移量为BX的数据相加,结果送入AL
mov ss:,al ; 把最相加结果送入目标 S 段偏移量为bx处
add bx,1 ; “指针”递增 1
loop s
mov ax,4c00h
int 21h
code ends
end start
调试结果
-d ds:0
0B4B:0000 01 02 03 04 05 06 07 08-00 00 00 00 00 00 00 00 ................
0B4B:0010 01 02 03 04 05 06 07 08-00 00 00 00 00 00 00 00 ................
0B4B:0020 02 04 06 08 0A 0C 0E 10-00 00 00 00 00 00 00 00 ................
0B4B:0030 B8 4B 0B 8E D8 BA 4C 0B-8E C2 BB 4D 0B 8E D3 BB .K....L....M....
0B4B:0040 00 00 B9 08 00 8A 07 26-02 07 36 88 07 83 C3 01 .......&..6.....
0B4B:0050 E2 F3 B8 00 4C CD 21 C0-22 89 86 FA FE 89 96 FC ....L.!.".......
0B4B:0060 FE C4 9E FA FE 26 8A 47-0C 2A E4 40 50 8B C3 05 .....&.G.*.@P...
0B4B:0070 0C 00 52 50 E8 19 46 83-C4 04 50 8D 86 00 FF 50 ..RP..F...P....P
-d es:0
0B4C:0000 01 02 03 04 05 06 07 08-00 00 00 00 00 00 00 00 ................
0B4C:0010 02 04 06 08 0A 0C 0E 10-00 00 00 00 00 00 00 00 ................
0B4C:0020 B8 4B 0B 8E D8 BA 4C 0B-8E C2 BB 4D 0B 8E D3 BB .K....L....M....
0B4C:0030 00 00 B9 08 00 8A 07 26-02 07 36 88 07 83 C3 01 .......&..6.....
0B4C:0040 E2 F3 B8 00 4C CD 21 C0-22 89 86 FA FE 89 96 FC ....L.!.".......
0B4C:0050 FE C4 9E FA FE 26 8A 47-0C 2A E4 40 50 8B C3 05 .....&.G.*.@P...
0B4C:0060 0C 00 52 50 E8 19 46 83-C4 04 50 8D 86 00 FF 50 ..RP..F...P....P
0B4C:0070 E8 6F 70 83 C4 06 B8 CD-05 50 8D 86 00 FF 50 E8 .op......P....P.
-d ss:0
0B4D:0000 02 04 06 08 0A 0C 0E 10-00 00 00 00 00 00 00 00 ................
0B4D:0010 B8 4B 0B 8E D8 BA 4C 0B-8E C2 BB 4D 0B 8E D3 BB .K....L....M....
0B4D:0020 00 00 B9 08 00 8A 07 26-02 07 36 88 07 83 C3 01 .......&..6.....
0B4D:0030 E2 F3 B8 00 4C CD 21 C0-22 89 86 FA FE 89 96 FC ....L.!.".......
0B4D:0040 FE C4 9E FA FE 26 8A 47-0C 2A E4 40 50 8B C3 05 .....&.G.*.@P...
0B4D:0050 0C 00 52 50 E8 19 46 83-C4 04 50 8D 86 00 FF 50 ..RP..F...P....P
0B4D:0060 E8 6F 70 83 C4 06 B8 CD-05 50 8D 86 00 FF 50 E8 .op......P....P.
0B4D:0070 CA 0C 83 C4 04 B8 FF FF-50 8D 86 00 FF 50 8D 46 ........P....P.F
) 用 push 指令将 a 段中 word 数据逆序存储到 b 段中。
assume cs:code
a segment
dw 1,2,3,4,5,6,7,8
a ends
b segment
dw 0,0,0,0,0,0,0,0
b ends
code segment
start:
mov ax,a
mov ds,ax ; 定义数据段 A
mov ax,b
mov es,ax ; 定义目标数据段 B
mov ax,0020h ; 定义栈使用安全空间
mov ss,ax ; 定义栈
mov sp,100
mov bx,0 ; 清零
mov cx,8
s0: push ds: ; 数据段偏移量为的数据压栈
add bx,2
loop s0
mov bx,0
mov cx,8
s1: pop es: ; 逆序弹出存到 B 段
add bx,2
loop s1
mov ax,4c00h
int 21h
code ends
end start
跟踪结果如下
-d es:0
0B4C:0000 08 00 07 00 06 00 05 00-04 00 03 00 02 00 01 00
0B4C:0010 B8 4B 0B 8E D8 B8 4C 0B-8E C0 B8 20 00 8E D0 BC
0B4C:0020 64 00 BB 00 00 B9 08 00-FF 37 83 C3 02 E2 F9 BB
0B4C:0030 00 00 B9 08 00 26 8F 07-83 C3 02 E2 F8 B8 00 4C
0B4C:0040 CD 21 87 BE 22 8B 97 C0-22 89 86 FA FE 89 96 FC
0B4C:0050 FE C4 9E FA FE 26 8A 47-0C 2A E4 40 50 8B C3 05
0B4C:0060 0C 00 52 50 E8 19 46 83-C4 04 50 8D 86 00 FF 50
0B4C:0070 E8 6F 70 83 C4 06 B8 CD-05 50 8D 86 00 FF 50 E8
[
Last edited by redtek on 2006-12-26 at 11:21 PM ]