ck17951 发表于 2017-12-14 01:45:04

一个关于程序6.1的疑问

assume cs:code
code segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
mov ax,0
mov bx,0
mov cx,8
s:add ax,cs:
add bx,2


loop s
mov ax,4c00h
int 21h
   

code ends
end   
这是程序6.1的代码 mov ax,0这一个指令在debug中用u命令不显示

但是在书中,
mov bx,0
mov ax,0

mov cx,8
顺序是这样的,在debug用u命令查看就显示出来了

求大神告诉原因

兰陵月 发表于 2017-12-14 09:30:46

本帖最后由 兰陵月 于 2017-12-14 09:31 编辑

我的和你的结果是一样的。
mov ax,0的机器码为B8 00 00,所以我们可以看到下图中这个机器码还是有的,红色下划线部分,而且是紧挨着mov bx,0,只不过因为debug反汇编的原因,导致这个B8 00 00机器码和前面区域的机器码连起来,变成别的指令了。:


在debug中执行的最终结果是不正确的。我们可以看到由于AX没有被赋值为零,而仍然是系统随机给的值0xFFFF,最后结果变成了0x7BDA,而不是正常的相加结果0x4BDB。
如下图:这是ax的初值,由于mov ax,0被debug错误反汇编,导致其初值仍为0xFFFF。


最后的相加结果变成了0x7BDA,而不是我们计算出来的0x4BDB。如下图:


兰陵月 发表于 2017-12-14 09:45:27

        assume cs:code,ds:data

        code segment
               
                mov ax,data
                mov ds,ax

                mov bx,0
                mov ax,0
                mov cx,8

        s:        add ax,
                add bx,2
                loop s
               
                mov ax,4c00h
                int 21h   

        code ends

        data segment
       
                dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
               
        data ends
       
                end

兰陵月 发表于 2017-12-14 09:47:41

兰陵月 发表于 2017-12-14 09:45


把数据段的定义放在代码段前面仍然会出现这个问题,最后我发现只要把数据段放在代码段后面,就不会出现问题。如下图,结果正确。

ck17951 发表于 2017-12-14 19:54:35

兰陵月 发表于 2017-12-14 09:47
把数据段的定义放在代码段前面仍然会出现这个问题,最后我发现只要把数据段放在代码段后面,就不会出现问 ...

多谢大神的回答,这个原因可能就是debug的原因了.给大神赞一个

ck17951 发表于 2017-12-14 20:04:42

ck17951 发表于 2017-12-14 19:54
多谢大神的回答,这个原因可能就是debug的原因了.给大神赞一个

可还是不知道为什么先mov bx,再mov ax,就是正确的原因

shishunfu 发表于 2017-12-14 21:52:16

在计算机的存储器中指令和数据没有任何区别,都是二级制信息。

你这里定义了16个字节的数据,
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
数据占了 段地址:000f

所以代码段的指令是从段地址:0010开始的
如你代码中的段地址为076a,则这段程序的代码段是从076a:0010开始的,
才会有 mov ax,0

ck17951 发表于 2017-12-15 03:21:31

shishunfu 发表于 2017-12-14 21:52
在计算机的存储器中指令和数据没有任何区别,都是二级制信息。

你这里定义了16个字节的数据,


是的,我晓得代码段是从:0010开始的
一楼的代码我用u 段地址:0010查看,结果是有mov ax,0000的
可是直接用u显示的地址076a:000f.下一个地址直接就是076a:0013.zh,中间没有0010这一地址显示mov ax,0

shishunfu 发表于 2017-12-15 09:26:21

ck17951 发表于 2017-12-15 03:21
是的,我晓得代码段是从:0010开始的
一楼的代码我用u 段地址:0010查看,结果是有mov ax,0000的
可是直接 ...

代码段,数据段是人为定义的,为了方便编程,只有你知道,在cpu看来都是二进制数据,你没有指定cpu从哪里开始读取指令,它就默认从最上往下都当作指令来读取。它把第一行的前15个字节数据段都当做不同的指令,把第16个字节数据 09 和第二行开始的b8 00 00当作了一天指令,即在cpu看来,b8 00 00 是mov ax,0; 09 b8 00 00就又是另外一条指令。为了让cpu把09 和b8分开来看, 这里你可以试一试把09 换成99,即把0987h 换成9987h(这个我自己测试是可以的).

兰陵月 发表于 2017-12-15 11:24:27

ck17951 发表于 2017-12-14 20:04
可还是不知道为什么先mov bx,再mov ax,就是正确的原因

作为一个程序,正常的情况下,它应该知道它该从哪里开始执行。

以王爽汇编书为例,应该定一个起始执行的标号start

比如说在mov ax,0前面加“start:”,运行就不会出现问题。

假如没有执行开始执行的位置,那么系统默认是在第一个位置开始运行。

第一个位置在本题中存储的是一些数据,反汇编后的指令意义,与我们原本设计的程序大相径庭。

因此结果就会不正确。

此题只需要在mov ax,0前面加上start:即可。

ck17951 发表于 2017-12-17 08:51:34

给二位点赞,有点明白了
页: [1]
查看完整版本: 一个关于程序6.1的疑问