会飞的熊 发表于 2012-12-9 00:59:15

8086汇编16章程序入口地址的直接定址表的问题

本帖最后由 会飞的熊 于 2012-12-9 01:00 编辑

      书中16.4的例题中关于将子程序的入口地址存储在一个表中的一段程序。         setscreen: jmp short set
             table: dw sub1,sub2,sub3,sub4
               set: push bx

                     cmp ah,3
                     ja sret
                     mov bl,ah
                     mov bh,0
                     add bx,bx

                     call word ptr table

               sret: pop bx
                     ret

1.上面的sub1,sub2,sub3,sub4地址标号,如果要取得他们的偏移地址值不是要offset吗,如果把他们当地址用不是只有数据标号才可以这这么用么?
2。table这里也把table当数据地址用了,如果可以把他们直接当地址用,还要offset干什么啊?

求大神解释。





lukelqz 发表于 2012-12-9 00:59:16

本帖最后由 lukelqz 于 2012-12-9 15:28 编辑

1.取得他们的偏移地址,其实不需要offset啦,编译器在遇到offset 标号和直接标号的时候,都是翻译的是他们的偏移地址。
第一张图:没有offset 直接标号。

第二张图:offset+标号

可以看到最后编译器编译完后,都是一样的,mov cx,003
说白了,offset是个伪指令,是给编译器看的,方便大家编程的,cpu可不认识。
2.关于offset
在16位汇编中,其实在要用到标号处的偏移地址的时候,加不加offset,编译器都能通过的。上面有图为证。

在win32汇编中更多的是用于 获取某个全局变量的偏移
如:
.data
szText            db'Win32 Assembly, Simple and powerful !',0
szCaption      db 'tips',0
.
.
.
.code
invoke MessageBox,NULL,offset szText,offset szCaption, MB_OK
这里就是获取szText的全局变量的偏移地址
offset还是挺有用的哈。


许你珍惜 发表于 2012-12-9 21:39:50

不解释,你懂得,问甲鱼哥

会飞的熊 发表于 2012-12-10 15:53:31

lukelqz 发表于 2012-12-9 00:59 static/image/common/back.gif
1.取得他们的偏移地址,其实不需要offset啦,编译器在遇到offset 标号和直接标号的时候,都是翻译的是他们的 ...

懂了,我来操作试试,谢谢解答啊。

会飞的熊 发表于 2012-12-10 16:52:18

本帖最后由 会飞的熊 于 2012-12-10 17:04 编辑

我自己实验的时候发现如果是mov ax,a编译器会自动添加一个步骤就是把s当成来用变成mov ax,
而mov ax,offset a,就是把是的偏移地址给ax,从图中可以看出两次赋值ax的值是不同的。是因为编译器的版本不同造成的的么

会飞的熊 发表于 2012-12-10 17:05:18

lukelqz 发表于 2012-12-9 00:59 static/image/common/back.gif
1.取得他们的偏移地址,其实不需要offset啦,编译器在遇到offset 标号和直接标号的时候,都是翻译的是他们的 ...

我的实验结果不同啊,是不同的编译器解释不同造成的么?

lukelqz 发表于 2012-12-10 17:33:33

把你代码发我,我去试一下,看看

会飞的熊 发表于 2012-12-10 18:40:31

assume cs:codeds:data

data segment
    db 128 dup(0)
data ends


code segment
start:

        mov ax,data
        mov ds,ax
       
        mov cx,128
a:        mov ax,1
s:   add ax,1
      loop s
       
        mov ax,offset a
        mov ax,a
       
      mov ax,4c00h
      int 21h

code ends
end start       
       

会飞的熊 发表于 2012-12-10 18:41:16

lukelqz 发表于 2012-12-10 17:33 static/image/common/back.gif
把你代码发我,我去试一下,看看

发了,你试试看。:handshake

lukelqz 发表于 2012-12-10 19:11:24

会飞的熊 发表于 2012-12-10 18:41 static/image/common/back.gif
发了,你试试看。

说两点,第一,你少了个逗号都能编译通过?
第二,我用的是MASM6.15,带ML编译的那个版本。运行结果和设想的完全一样。没有问题。
下面是我的调试图。

会飞的熊 发表于 2012-12-10 21:09:56

lukelqz 发表于 2012-12-10 19:11 static/image/common/back.gif
说两点,第一,你少了个逗号都能编译通过?
第二,我用的是MASM6.15,带ML编译的那个版本。运行结果和设 ...

少了个逗号通过了编译,不过加了逗号结果还是一样的。
我用的是5.0,组合使用的masm和link ,应该是编译器的问题 ,我来下个6.15试试。

lukelqz 发表于 2012-12-10 21:15:24

会飞的熊 发表于 2012-12-10 21:09 static/image/common/back.gif
少了个逗号通过了编译,不过加了逗号结果还是一样的。
我用的是5.0,组合使用的masm和link ,应该是编译 ...

恩。是编译器的问题,没必要在这个问题上深究了,知道自己要什么功能,该怎么用就行了。

会飞的熊 发表于 2012-12-10 21:22:21

lukelqz 发表于 2012-12-10 21:15 static/image/common/back.gif
恩。是编译器的问题,没必要在这个问题上深究了,知道自己要什么功能,该怎么用就行了。

是滴。。。:loveliness:
页: [1]
查看完整版本: 8086汇编16章程序入口地址的直接定址表的问题