0

i am new to asm and emu86. i wrote the folowing code

org 100h

;variabls
var1 dw 21

;start of the program
main:

    mov     ax,var1

however when i am emulate ax stores the value a100h

enter image description here

i am expecting to ax to be 21 but instead ax stores the value 0xa100.

what did i do wrong?

i declared var1 to be equal 21 and moved it to ax. but somehow ax equal 0xa100

  • Are you sure you set a breakpoint right after that instruction? The code in your disassembly window looks like execution ended up somewhere else after decoding later bytes in memory as other instructions, some of which also modified AX. (Your program doesn't exit with a DOS call, or with `ret` which works in .com executables because the top of stack ("return address") is a pointer to code that makes an exit call.) – Peter Cordes Aug 19 '23 at 08:09
  • [Sourced guess](https://gcallah.github.io/Emu86/area.html): if you want the value of a variable and not its address, put it in square brackets. – teapot418 Aug 19 '23 at 08:20
  • 2
    Also you seem to be executing through the location where the variable is stored(?). Maybe jump around it or something... – teapot418 Aug 19 '23 at 08:24
  • 1
    @teapot418: emu8086's assembly dialect is MASM-like; `mov reg, symbol` is a load even without square brackets. And `A100` wouldn't be the offset. Oh, the offset would be `0100` because that data is the first 2 bytes of the program, where it gets executed as code... As 0Signal points out, `15` is the start of a 3-byte instruction that "eats" the A1 opcode for the `mov ax, moffs16` instruction. Yeah, put the data later. [Assembly (x86): db 'string',0 does not get executed unless there's a jump instruction](https://stackoverflow.com/q/30561366) – Peter Cordes Aug 19 '23 at 09:09

1 Answers1

3
  1. .com files are plain binary.

  2. org 100h sets starting offset for the code.

  3. var1 is erroneously treated as code not program's data.

  4. Variable definition var1 dw 21 in memory looks like: 15 00.

    The instruction that starts with code 15 is:

    adc ax,imm16

    This instruction uses 3 bytes, and the 3rd byte is taken from the line mov ax, var1 which in memory is A1 00 01 (mov ax, moffs16, 0100 is var1 offset). Remaining bytes 00 01 form instruction add [bx + di], al (00 /r, ADD r/m8, r8).

  5. Solution is to use jmp to skip the bytes 15 00 (var1 dw 21).

org 100h            ; .com file

jmp start           ; EB 02

    var1 dw 21      ; 15 00

start:
    mov ax,var1     ; A1 02 01

    cmp ax,0        ; 3D 00 00

    mov ax,4c00h    ; B8 00 4C
    int 21h         ; CD 21

    ret             ; C3
Sep Roland
  • 33,889
  • 7
  • 43
  • 76
Nassau
  • 377
  • 1
  • 1
  • 8
  • 1
    *Somehow byte A1 is shared with 2 instructions* - When the CPU decodes this sequence of bytes, the `A1` byte is part of the `ADC AX, 0A100` instruction we see in the disassembly. The CPU will start decoding the next instruction at `00 01`, a memory-destination `add` with `AL` as the source. So yes, machine-code instruction boundaries (*from that start-point for decoding*) are out of sync with source lines. x86 machine code is a byte stream that's not self-synchronizing; there are no instruction boundaries unless/until you pick a starting point to decode from. – Peter Cordes Aug 19 '23 at 09:14
  • I write faster than think sometimes. :D I updated my answer, I hope it is better now. :) – Nassau Aug 19 '23 at 10:14