汇编代码跳过一条线?

-2 x86 assembly x86-16

为什么我的汇编代码跳过一行?它一直在跳线mov AX,A

org 100h
count equ 2
A DW 5
B DW 6
Y0 DW ?
Y1 DW ?    
mov AX,A     
add AX,B
sub AX,count
mov Y0,AX
mov BX,B
neg BX
add BX,count
mov Y1,BX 
ret
Run Code Online (Sandbox Code Playgroud)

Cod*_*ray 6

让我们看看这些指令助记符汇编到的代码字节:

               org 100h
               count equ 2
05 00          A DW 5
06 00          B DW 6
00 00          Y0 DW ?
00 00          Y1 DW ?    
A1 00 01       mov AX,A       ;NASM "mov ax, [A]"
03 06 02 01    add AX,B       ;NASM "add ax, [B]"
83 E8 02       sub AX,count
...
Run Code Online (Sandbox Code Playgroud)

代码字节在左边; 指令助记符(您向汇编程序提供的部分)位于右侧.一切看起来都不错吧?

那么,现在让我们看看当我们组装然后反汇编代码时会发生什么:

05 00 06           add ax,0x600
00 00              add [bx+si],al
00 00              add [bx+si],al
00 B8 00 01        add [bx+si+0x100],bh
05 02 01           add ax,0x102
83 E8 02           sub ax,byte +0x2
Run Code Online (Sandbox Code Playgroud)

等等......发生了什么事?!字节(左侧)是相同的,但指令助记符都是不同的!它们与你最初写的不一样!

发生的事情是,代码顶部的数据声明都由汇编器尽职尽责地翻译成字节,但反汇编程序将这些(数据)字节转换回可执行代码.它没有意识到它们是数据,因此它试图将它们解释为要执行的指令.这不仅导致错误的指令,而且还引入了一个混乱下游的帧移位突变.

所以它实际上并没有"跳过"指令mov ax, a.就计算机而言,该指令甚至不再存在.它正在执行您在第二个代码块中看到的指令.基本上,它正在执行废话.记住:在汇编程序中,一切都只是字节!

解决方案应该是显而易见的:不要将数据声明与可执行代码混合在一起.最好的办法是将数据下移到底部,在所有可执行代码下面,执行永远不会得到:

org 100h
count equ 2

mov AX,A     
add AX,B
sub AX,count
mov Y0,AX
mov BX,B
neg BX
add BX,count
mov Y1,BX 
ret

A DW 5
B DW 6
Y0 DW ?
Y1 DW ?  
Run Code Online (Sandbox Code Playgroud)

引入空格有助于将事物分解为逻辑块,使代码更具可读性.请注意,我已将ORG指令保留在顶部,因为它需要在那里.我也没有将EQU指令移到底部.可以把它留在那里因为它只是定义了一个组装时间常数.正如您从一开始所看到的,它不会转换为生成的机器代码中的任何字节.

如果您不想因任何原因移动数据,那么您必须插入一条指令来跳过它:

org 100h
count equ 2

jmp Begin

A DW 5
B DW 6
Y0 DW ?
Y1 DW ?    

Begin:
    mov AX,A     
    add AX,B
    sub AX,count
    mov Y0,AX
    mov BX,B
    neg BX
    add BX,count
    mov Y1,BX 
    ret
Run Code Online (Sandbox Code Playgroud)