鱼C论坛

 找回密码
 立即注册
查看: 20|回复: 19

3.4 mov [2],bx为什么ds:1b12??

[复制链接]
发表于 前天 15:25 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
bx=1b12
mov [2],bx                ds:0002=1122
-t
add [ bx+si],al                              ds:1b12=00
为什么ds:0002变成ds:1b12???
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 前天 15:25 | 显示全部楼层
不是 ds:0002 变成了 ds:1b12,而是两条指令访问的地址不同。

  1. mov [0002], bx   ; [0002] 是直接寻址,偏移地址固定为 0002
  2. add [bx], al     ; [bx] 是寄存器间接寻址,偏移地址来自 BX
复制代码


执行 mov [0002], bx 时,BX=1B12,所以数据写到 DS:0002 和 DS:0003(小端:0002 存 12,0003 存 1B)。

执行 add [bx], al 时,BX 还是 1B12,所以 CPU 算出的地址是 DS:1B12,它改的是 DS:1B12,不会去改 DS:0002。

Debug/emu8086 旁边显示 ds:1b12=00,只是告诉你当前这条指令要操作的内存单元是 DS:1B12,并不是上一条的 DS:0002 变成了 DS:1B12。

如果想让 add 也操作 DS:0002,可以写:

  1. add [0002], al
复制代码


或:

  1. mov bx, 0002
  2. add [bx], al
复制代码


另外,BX=1B12 时 mov [0002], bx 后 DS:0002 处字节应为 12,DS:0003 处为 1B;如果你看到 1122,需要检查 BX 的值或显示方式。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 前天 16:24 | 显示全部楼层
FishC 发表于 2026-10-9 15:25
不是 ds:0002 变成了 ds:1b12,而是两条指令访问的地址不同。

谢谢,另外为什么
-a
mov [0],cs
出错??
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 前天 16:24 | 显示全部楼层
531035528 发表于 2026-10-09 16:24
FishC 发表于 2026-10-9 15:25
不是 ds:0002 变成了  ...


你写的 mov ,cs 逗号前面是空的,MOV 指令必须有两个操作数,所以 Debug 会直接报语法错误。

如果你原本想写的是:

  1. mov [2],cs
复制代码


这是合法的,表示把 CS 的值存到 DS:0002 开始的内存里。

如果你原本想写的是:

  1. mov cs,ax
  2. mov cs,[2]
复制代码


那会出错,因为 8086 不允许把数据送入 CS。CS 只能作为源操作数,不能作为目标操作数。

要改变 CS,只能用远跳转、远调用、中断返回等,例如:

  1. jmp 1234:5678
  2. call 1234:5678
  3. retf
  4. iret
复制代码


简单记:CS 可以读出来,不能直接用 MOV 写进去。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 前天 16:30 | 显示全部楼层
FishC 发表于 2026-10-9 16:24
你写的 mov ,cs 逗号前面是空的,MOV 指令必须有两个操作数,所以 Debug 会直接报语法错误。

如果你 ...

-a
mov [0],cs
出错??
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 前天 16:30 | 显示全部楼层
531035528 发表于 2026-10-09 16:30
FishC 发表于 2026-10-9 16:24
你写的 mov ,cs 逗号 ...


问题可能出在论坛把方括号吃掉了。

你原本想写的应该是:

  1. mov [2],cs
复制代码


但在 Discuz 里直接写方括号,容易被当成 BBCode 标签解析,结果显示出来就变成了:

  1. mov ,cs
复制代码


Debug 看到的是逗号前面没有目标操作数,所以直接报语法错误。

如果原意是
  1. mov [2],cs
复制代码
,这是合法的,表示把 CS 的值写入 DS:0002 和 DS:0003。

如果确实写的是
  1. mov ,cs
复制代码
,那当然出错,因为 MOV 必须有两个操作数。

另外,
  1. mov cs,ax
复制代码
才是非法的,因为 CS 不能作目标操作数。

以后发代码时,用
  1. ...
复制代码
包起来,方括号就不会被论坛解析掉了。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 前天 16:34 | 显示全部楼层
FishC 发表于 2026-10-9 16:30
问题可能出在论坛把方括号吃掉了。

你原本想写的应该是:
  1. -a
  2. mov [0],cs
复制代码

出错??
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 前天 16:34 | 显示全部楼层
531035528 发表于 2026-10-09 16:34
FishC 发表于 2026-10-9 16:30
问题可能出在论坛把方 ...


你看到的 mov ,cs 其实是论坛把方括号吃掉了,原命令应该是:


  1. mov [2], cs
复制代码


在 8086 里,mov [2], cs 本身是合法的,表示把 CS 的值写入 DS:0002 和 DS:0003。

但 Debug 的汇编器比较简陋,可能不支持这种写法,所以会报错。

你可以用通用寄存器中转:


  1. mov ax, cs
  2. mov [2], ax
复制代码


这样就能把 CS 的值写到 DS:0002。

如果你真的输入的是 mov ,cs,那当然出错,因为 MOV 必须有两个操作数。

另外,mov cs, [2] 也是非法的,因为 CS 不能作目标操作数,只能作源操作数。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 前天 16:38 | 显示全部楼层
FishC 发表于 2026-10-9 16:34
你看到的 mov ,cs 其实是论坛把方括号吃掉了,原命令应该是:

我在dbox中使用,为什么报错??
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 前天 16:39 | 显示全部楼层
531035528 发表于 2026-10-09 16:38
FishC 发表于 2026-10-9 16:34
你看到的 mov ,cs 其 ...


在 dbox(DOSBox)的 debug 里,用 A 命令汇编时,mov [2],cs 报错是正常的。

原因是 Debug 自带的汇编器太简陋,不支持把 CS 直接作为源操作数写入内存这种写法。它只认一些简单形式。

解决办法:先用通用寄存器中转,再写入内存:


  1. mov ax, cs
  2. mov [2], ax
复制代码


这样就能把 CS 的值写到 DS:0002 和 DS:0003。

如果还想用 BX 间接寻址,也可以这样:


  1. mov bx, 2
  2. mov [bx], cs
复制代码


简单记:Debug 里不要直接写 mov [2],cs,用 AX 中转最稳。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 前天 17:01 | 显示全部楼层
FishC 发表于 2026-10-9 16:39
在 dbox(DOSBox)的 debug 里,用 A 命令汇编时,mov [2],cs 报错是正常的。

原因是 Debug 自带的 ...

add ds,ax
也出错了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 前天 17:01 | 显示全部楼层
531035528 发表于 2026-10-09 17:01
FishC 发表于 2026-10-9 16:39
在 dbox(DOSBox)的  ...


因为 8086 里段寄存器不能直接做算术运算。

add ds, ax 这种写法是非法的,CPU 根本没有这条指令。

段寄存器 DS、CS、ES、SS 能用的操作只有这几种:

- mov ds, ax
- mov ax, ds
- push ds
- pop ds

像 add、sub、inc、dec 这类算术指令,都不能直接作用在段寄存器上。

想给 DS 加 AX,必须用通用寄存器中转:


  1. mov bx, ds
  2. add bx, ax
  3. mov ds, bx
复制代码


或者:


  1. mov ax, ds
  2. add ax, bx
  3. mov ds, ax
复制代码


简单记:段寄存器只能整体搬进搬出,不能直接参与加减。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 前天 17:16 | 显示全部楼层
FishC 发表于 2026-10-9 16:34
你看到的 mov ,cs 其实是论坛把方括号吃掉了,原命令应该是:

为什么
  1. mov cs,[2]
复制代码

出错??
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 前天 17:16 | 显示全部楼层
531035528 发表于 2026-10-09 17:16
FishC 发表于 2026-10-9 16:34
你看到的 mov ,cs 其 ...


因为 CS 是代码段寄存器,它只能作为源操作数,不能作为目标操作数。

也就是说,任何想把数据送进 CS 的 MOV 指令都是非法的,比如:


  1. mov cs, ax
  2. mov cs, bx
  3. mov cs, [2]
复制代码


这些在 8086 里都没有对应的机器指令,所以 Debug 会报错。

合法的是把 CS 读出来,例如:


  1. mov ax, cs
  2. mov [2], ax
复制代码


要改变 CS,不能用 MOV,只能用远跳转、远调用、中断返回等:


  1. jmp 1234:5678
  2. call 1234:5678
  3. retf
  4. iret
复制代码


另外,如果你写的是 mov cs, 逗号后面是空的,那是缺少源操作数,Debug 也会报语法错误。

简单记:CS 只读不写,MOV 不能把数据送进 CS。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 前天 17:23 | 显示全部楼层
FishC 发表于 2026-10-9 17:16
因为 CS 是代码段寄存器,它只能作为源操作数,不能作为目标操作数。

也就是说,任何想把数据送进 C ...

为什么
  1. mov [0],cs
复制代码
地
在86机可行,在dbox中不行??
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 前天 17:23 | 显示全部楼层
531035528 发表于 2026-10-09 17:23
FishC 发表于 2026-10-9 17:16
因为 CS 是代码段寄存 ...


不是 CPU 的问题,是 DOSBox 里 debug 自带汇编器的限制。

mov [2], cs 这条指令本身在 8086 上是合法的,机器码存在,功能就是把 CS 写到 DS:0002。

它在 emu8086、MASM、TASM 这些正经汇编器里都能通过,因为它们认得“段寄存器作源操作数写入内存”这种形式。

但 DOSBox 的 debug 里,A 命令用的汇编器非常简陋,只认几种固定写法,比如:


  1. mov ax, bx
  2. mov ax, 1234
  3. mov [2], ax
  4. mov ax, [2]
复制代码


它不认识 mov [2], cs 这种,所以直接报错。

想在 DOSBox 里达到同样效果,用 AX 中转:


  1. mov ax, cs
  2. mov [2], ax
复制代码


简单记:指令合法,是 debug 的汇编器太弱,不是 86 机做不到。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 前天 17:27 | 显示全部楼层
FishC 发表于 2026-10-9 17:23
不是 CPU 的问题,是 DOSBox 里 debug 自带汇编器的限制。

mov [2], cs 这条指令本身在 8086 上是合 ...

在86机
  1. mov cs,[0]
复制代码

可以??
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 前天 17:27 | 显示全部楼层
531035528 发表于 2026-10-09 17:27
FishC 发表于 2026-10-9 17:23
不是 CPU 的问题,是  ...


不可以。

mov cs, ... 在任何 8086/8088 机器上都是非法指令,因为 CS 不能作为目标操作数。

合法的是把 CS 当源操作数读出来:


  1. mov ax, cs
  2. mov [2], ax
复制代码


想改变 CS,只能用:


  1. jmp 1234:5678
  2. call 1234:5678
  3. retf
  4. iret
复制代码


所以不是 DOSBox 的限制,是 8086 本身就不允许用 MOV 写 CS。

如果你写的是 mov cs, 逗号后面空着,那是缺少源操作数,Debug 会先报语法错误;就算补上操作数,比如 mov cs, ax,也是非法指令。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 前天 17:30 | 显示全部楼层
FishC 发表于 2026-10-9 17:27
不可以。

mov cs, ... 在任何 8086/8088 机器上都是非法指令,因为 CS 不能作为目标操作数。

那为什么86机
  1. mov ds,[0]
复制代码

可行呢??
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 前天 17:30 | 显示全部楼层
531035528 发表于 2026-10-09 17:30
FishC 发表于 2026-10-9 17:27
不可以。

mov cs,  ...


因为 DS 和 CS 在 8086 里的地位不一样。

DS 是数据段寄存器,只影响数据访问,所以允许用 MOV 直接赋值,比如:


  1. mov ds, ax
  2. mov ds, bx
  3. mov ds, [bx]
复制代码


CS 是代码段寄存器,和 CPU 下一条要执行的指令地址绑定。如果允许随便 MOV 改 CS,程序很容易跑飞,所以硬件直接禁止用 MOV 写 CS。

所以:

- mov ds, ax 合法
- mov cs, ax 非法

要改 CS 只能用:


  1. jmp 1234:5678
  2. call 1234:5678
  3. retf
  4. iret
复制代码


另外,如果你写的是 mov ds, 后面空着,那还是语法错误,因为 MOV 必须有两个操作数。

简单记:DS、ES、SS 可以 MOV 写入,CS 只能读不能写。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2026-10-11 01:08

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表