功能:将程序中定义的数据逆序存放
要搞清楚一点 .exe 文件加载的过程
1.先是找到一段起始地址为 SA:0000 (即起始地址的偏移地址为0 )的容量足够的空闲内存区 SA值 正是放在 DS中的
2.然后在这段内存区的前256个字节中,创建一个称为程序段前缀(PSP)的数据区,就是先用256个字节作为 PSP的数据区,这个东西暂时还不清楚是啥? 反正DOS 是要通过PSP来和被加载的程序通信,且把它当做是 电话线
3.接着,PSP之后 也就是 地址变成了 SA:100 也就是相当于 段地址更为了 SA + 10H 对应的地址就是 SA+10H:0 现在才开始放程序!!程序是什么,程序就是 源代码中的,数据和指令 当然 有用到 DW 定义字型数据时 先是安置这些数据 安置好了 再放指令!!!
通过上面的加载分析,我想讲的是,数据段的起始位置是PSP之后的地址, 而不是放在 PSP这个所谓的段前缀里 此处我之前有些误解!!
assume cs:codesg
codesg segment
dw 01223h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h ; 这一段数据的位置是 CS:0--CS:F 总共 16个字节
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 这一段数据的位置是 CS:10--CS:2F 总共 32 个字节 有意思!!
;define Word 就是 dw 此处定义了这么多的字空间,干嘛呢?
其实,后面的 0 根本就没有什么实际意义,只不过是来帮忙占个位置
这里定义了总共 16 个字 0, 也就是对应的向系统所要了 32 个字节的空间,系统会用32个字节来存放它们,实际上此处的定义没有实际的定义意义,就是通过定义的方式向系统所要 32 个字节的空间 ,就是 开辟 32 个字节的空间
start: mov ax,cs ;CS 是 程序段地址
mov ss,ax ;确定栈的段地址 即 栈段地址 栈段地址也设置成了程序段地址
mov sp,30h ;SP 的初始指向位置就是栈底 就是封界 就是死口 形成栈
这里的 30H 也是有来历的,当然会有,不然谁会没事瞎扯一个呢?
好的,来讲讲 为什么是 30H
SP 初始化为 30H 而 SP 永远指向栈顶 所以 就是说 这个栈的栈顶刚开始是 SS:30H
而SS 就是 CS 所以 刚开始的栈顶就是 CS:30H
为什么 是30H 而不是 32H ???
我想这应该是一个小小的节省空间的方法 就是,额,要先理解这个程序,逆序嘛,先让大家入栈, 哎呀! 这个栈是从 CS:10 开始的
对应的栈空间就是
mov bx,0
mov cx,8
s: push ss:[bx] ;这就是压栈 此处就是把 SS:[BX] (以SS为段地址,BX为偏移地 址的内存单元的数据)压入上面已经设置好的栈
add bx,2
loop s
mov bx,0
mov cx,8
s0: pop cs:[bx]
add bx,2
loop s0
mov 4c00h
int 21h
codesg ends
end start
我一直认为,思考是很重要的
下面我来记录我的思考过程
要搞清楚一点 .exe 文件加载的过程
1.先是找到一段起始地址为 SA:0000 (即起始地址的偏移地址为0 )的容量足够的空闲内存区 SA值 正是放在 DS中的
2.然后在这段内存区的前256个字节中,创建一个称为程序段前缀(PSP)的数据区,就是先用256个字节作为 PSP的数据区,这个东西暂时还不清楚是啥? 反正DOS 是要通过PSP来和被加载的程序通信,且把它当做是 电话线
3.接着,PSP之后 也就是 地址变成了 SA:100 也就是相当于 段地址更为了 SA + 10H 对应的地址就是 SA+10H:0 现在才开始放程序!!程序是什么,程序就是 源代码中的,数据和指令 当然 有用到 DW 定义字型数据时 先是安置这些数据 安置好了 再放指令!!!
通过上面的加载分析,我想讲的是,数据段的起始位置是PSP之后的地址, 而不是放在 PSP这个所谓的段前缀里 此处我之前有些误解!!
assume cs:codesg
codesg segment
dw 01223h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h ; 这一段数据的位置是 CS:0--CS:F 总共 16个字节
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 这一段数据的位置是 CS:10--CS:2F 总共 32 个字节 有意思!!
;define Word 就是 dw 此处定义了这么多的字空间,干嘛呢?
其实,后面的 0 根本就没有什么实际意义,只不过是来帮忙占个位置
这里定义了总共 16 个字 0, 也就是对应的向系统所要了 32 个字节的空间,系统会用32个字节来存放它们,实际上此处的定义没有实际的定义意义,就是通过定义的方式向系统所要 32 个字节的空间 ,就是 开辟 32 个字节的空间
start: mov ax,cs ;CS 是 程序段地址
mov ss,ax ;确定栈的段地址 即 栈段地址 栈段地址也设置成了程序段地址
mov sp,30h ;SP 的初始指向位置就是栈底 就是封界 就是死口 形成栈
这里的 30H 也是有来历的,当然会有,不然谁会没事瞎扯一个呢?
好的,来讲讲 为什么是 30H
SP 初始化为 30H 而 SP 永远指向栈顶 所以 就是说 这个栈的栈顶刚开始是 SS:30H
而SS 就是 CS 所以 刚开始的栈顶就是 CS:30H
为什么 是30H 而不是 32H ???
我想这应该是一个小小的节省空间的方法 就是,额,要先理解这个程序,逆序嘛,先让大家入栈, 哎呀! 这个栈是从 CS:10 开始的
对应的栈空间就是
mov bx,0
mov cx,8
s: push ss:[bx] ;这就是压栈 此处就是把 SS:[BX] (以SS为段地址,BX为偏移地 址的内存单元的数据)压入上面已经设置好的栈
add bx,2
loop s
mov bx,0
mov cx,8
s0: pop cs:[bx]
add bx,2
loop s0
mov 4c00h
int 21h
codesg ends
end start
我一直认为,思考是很重要的
下面我来记录我的思考过程