Assembly code skipping a line?

后端 未结 2 822
悲&欢浪女
悲&欢浪女 2021-01-29 11:56

Why is my assembly code skipping a line? It keeps skipping the line mov AX,A

org 100h
count equ 2
A DW 5
B DW 6
Y0 DW ?
Y1 DW ?    
mov AX,A     
ad         


        
2条回答
  •  无人及你
    2021-01-29 12:21

    Let's see what code bytes these instruction mnemonics would assemble to:

                   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
    ...
    

    The code bytes are on the left; the instruction mnemonics (the part you feed to the assembler) are on the right. All looks good, right?

    Well, now let's see what happens when we assemble and then disassemble the code:

    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
    

    Wait…what happened?! The bytes (on the left) are the same, but the instruction mnemonics are all different! They're not the same ones you originally wrote!

    What happened is, the data declarations that were at the top of your code were all dutifully translated into bytes by the assembler, but then the disassembler translated those (data) bytes back into executable code. It didn't realize they were data, so it tried to interpret them as instructions to be executed. This resulted not only in the incorrect instructions, but also introduced a frameshift mutation that messed up everything downstream.

    So it's not actually "skipping" the instruction mov ax, a. That instruction isn't even there anymore, as far as the computer can tell. It is executing the instructions that you see in the second block of code. Basically, it is executing nonsense. Remember: in assembler, everything is just bytes!

    The solution should be obvious: don't mix data declarations in with your executable code. The best thing to do would be to move the data down to the bottom, below all of your executable code, where execution will never get:

    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 ?  
    

    Introducing whitespace helps to break things up into logical chunks, making the code more readable. Notice that I've left the ORG directive at the top, because it needs to be there. I also didn't move the EQU directive to the bottom. It's okay to leave that there because it just defines an assemble-time constant. As you can see from the very beginning, it isn't translated into any bytes in the resulting machine code.

    If you didn't want to move the data for whatever reason, then you would have to insert an instruction to jump over it:

    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
    

提交回复
热议问题