DOS EXE起始地址的确定

前段时间看到有人讨论DOS EXE的加载过程,讨论其起始地址是如何确定的? 解决问题最好的办法就是实践:

写一段最简单的汇编
        STSG SEGMENT STACK 'S'
            DW 32 DUP(?)
        STSG ENDS
        DATA SEGMENT
            A DW 123
            B DW 456
            SUM DW ?
        DATA ENDS
        CODE SEGMENT
            MAIN PROC FAR
                ASSUME CS:CODE, DS:DATA, SS:STSG, ES:NOTHING
                PUSH DS
                XOR AX, AX
                PUSH AX
                MOV AX, DATA
                MOV DS, AX
                MOV AX, A
                ADD AX, B
                MOV SUM, AX
                RET
            MAIN ENDP
        CODE ENDS
            END MAIN
使用MASM5编译
    MASM test.asm
    LINK test.obj


网上查知DOS文件头信息如下:
    EXE文件头信息
    ―――――――――――――――――――
    ├ 偏移量 ┤ 意义 ┤
    ├00h-01h ┤MZ'EXE文件标记 ┤
    ├2h-03h  ┤文件长度除512的余数 ┤
    ├04h-05h ┤...............商 ┤
    ├06h-07h ┤重定位项的个数 ┤
    ├08h-09h ┤文件头除16的商 ┤
    ├0ah-0bh ┤程序运行所需最小段数 ┤
    ├0ch-0dh ┤..............大.... ┤
    ├oeh-0fh ┤堆栈段的段值 (SS) ┤
    ├10h-11h ┤........sp ┤
    ├12h-13h ┤文件校验和 ┤
    ├14h-15h ┤IP ┤
    ├16h-17h ┤CS ┤
    ├18h-19h ┤............ ┤
    ├1ah-1bh ┤............ ┤
    ├1ch ┤............ ┤

使用UltraEdit打开test.exe, 16h - 17 h为05 00 也就是05:00
我们再拿Debug运行test.exe
debug test.exe
-r
可以看到
    DS:1810 CS:1825 SS:1820 SP:0040
-u可以看到1825:0000正好是CODE段的第一条语句PUSH DS

静态的算一下:
    CODE段前面有STSG 32个DW,共64个字节换成地址就是40H, DATA段共3个DW, 也就是6个字节, 但段地址至少也是1:0也就是10H(16)字节的整数倍,正好50H个字节,也就是5:0。正好就是CODE段的距离起始的偏移值

再动态的算一下, Dos载入EXE时,最前面是PSP头,此时DS和ES指向的就是PSP起始地址,而且PSP是固定大小256字节 = 100H = 10:0
后面就是EXE中的内容,首先是STSG段,应该是DS + 10 正好我们看到SS就是1820 = 1810(DS) + 10, SP为0040,也就是STSG段的大小(64个字节)。接下来就是DATA段,也就是说DATA段应该是1824:0,通过-u,我们可以看到
1825:0004 MOV AX, 1824 也就是源码中的MOV AX, DATA, DATA正是我们预期的1824, DATA段正如前面分析,不够10H个字节,但占10H,所以下一个段地址1825H就是CODE段了。

这里没解决为什么记录到EXE头里的就是CODE起始地址,
看源码有两处可能,一是ASSUME CS:CODE,而是END MAIN。这都是伪指令,究竟是哪条伪指令影响了assembler呢?很简单,把ASSUME注释掉,再试验前面的过程,发现没变化。把END MAIN 换成END,再试验,结果就不一样了。
EXE 投中 16 - 17h变成了00 00,debug -r 显示CS指向也错误了,和SS指向了一起(因为CS的指就来自程序首地址 + PSP大小 +头中的偏移值)

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值