You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用emu8086实现字符串复制时遇未知操作码错误的问题排查

嘿,我来帮你拆解这个emu8086的汇编问题~

错误含义先搞懂
  • unknown opcode skipped: 64:这个错误是说模拟器碰到了它认不出来的操作码64(这其实是x86架构里FS段寄存器的前缀指令),为啥会出现?因为你的代码语法写错了,导致汇编器生成了无效的机器码,模拟器只能跳过这个错误指令继续执行。
  • not 8086 instruction - not supported yet:意思是你写的代码里有不符合8086指令集规范的写法,或者用了emu8086还不支持的指令/语法。
你的代码里到底错在哪?

咱们逐行揪问题:

1. mov di, a 写法完全错误

在8086汇编里,如果你想把变量a的内存地址放到di寄存器里,直接写mov di, a是不行的——汇编器会把这个错误写法解析成带FS段前缀的指令,也就是那个导致64错误的元凶。正确的写法有两种:

lea di, a       ; 把a的有效地址加载到di

或者

mov di, offset a ; 直接把a的偏移地址赋值给di

2. mov a, di 类型不匹配还逻辑多余

你定义的a是字节型变量(db 0),但di是16位寄存器,8086根本不允许把16位的数据塞进一个字节单元里,这属于类型不匹配的错误。而且从逻辑上来说,这行完全没必要:你已经用di指向了a的起始地址,复制完成后a里已经存好字符串了,直接用a的地址就行,根本不用把di的值存回a。

3. mov dx, a 没传对地址

int 21h的09h功能要求dx指向字符串的首地址,而且这个字符串得用$结尾(不是你用的0)。你直接写mov dx, a会把a这个字节里的数值加载到dx,这显然不是你要的地址。正确的写法是:

lea dx, a

或者

mov dx, offset a

4. 字符串结束符不匹配

你的msg用0结尾,但int 21h的09h功能只认$作为结束标记,所以复制后的字符串结尾是0的话,会导致输出乱码直到找到$。最简单的解决办法是把msg的定义改成:

msg: db "Hello, World!", '$'
修正后的完整代码
org 100h 
jmp start 

msg: db "Hello, World!", '$'  ; 用$适配09h功能的结束要求
a: db 13 dup(0)                ; 给目标字符串留足够空间,避免溢出

start: 
    mov si, offset msg         ; 加载源字符串地址到si
    lea di, a                  ; 加载目标地址到di
    call _make_str
    
    lea dx, a                  ; 把目标字符串地址传给dx
    mov ah, 09h 
    int 21h 
    
    mov ah, 0 
    int 16h 
    ret 

_make_str: 
    pusha 
_next: 
    mov al, [si] 
    mov [di], al 
    inc si 
    inc di 
    cmp al, '$'                ; 以$作为循环结束条件
    jne _next 
    popa 
    ret 

这样修改后,代码应该就能正常复制字符串并输出了~

内容的提问来源于stack exchange,提问作者Pantokrator

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:34:04