ShadowViper
ShadowViper

Reputation: 365

Running X86 Assembly on Win8 64 bit

I'm new to assembly and am trying to create replicate the folium of descartes (x^3 + y^3 - 3*axy = 0 where a=12). I have the code done and when i compile and link, i get no error. Im using TASM through DOSBox 0.74 on a win8 64-bit. But when i try to execute the folium.exe file though the DOSBox, i get lines of random characters with it saying unable to open file in the center of the random characters. I dont know why such is happening, it should show '0' or ' ' according to my code. Either im assembling wrong or something is wrong in my code that im not aware of.

In DOSBox 0.74, i simply type TASM folium.asm, then LINK folium and then folium to execute. Thats the way i did it for my other code and it worked.

title   folium.asm  ; draws the loop in a cubic curve called the folium of Descartes, defined by x^3 + y^3 - 3*a*x*y = 0, where a = 12
    .model  small
    .stack  100h

    .data
    include const.inc

x   dw  ?
y   dw  ?
z   dw  ?

    .code

main    proc

; initialize DS
    mov ax, @data
    mov ds, ax

; y := 0;
    mov y, 0

while01: ; y <= 20
    cmp y, 20
    jnle    endwhile01

; do01
; x := 0
    mov x, 0

while02: ; x <= 20
    cmp x, 20
    jnle    endwhile02

; do01
; z := x*x*x + y*y*y - 36*x*6
    mov ax, x
    imul x
    imul x
    mov z, ax
    mov ax, y
    imul y
    imul y
    add z, ax
    mov ax, 36
    imul x
    mov bx, ax
    mov ax, 6
    imul bx
    sub z, ax

; if01 z <= 0
    cmp x, 0
    jnle    else01

then01:
; write '0'
    mov ah, dispstr
    mov dx, offset '0'
    int dosfunc
    jmp endif01

else01:
; write ' '
    mov ah, dispstr
    mov dx, offset ' '
    int dosfunc

endif01:
; x := x + 1;
    inc x
    jmp while02

endwhile02:
; write cr, lf
    mov ah, wrchr
    mov dl, cr
    int dosfunc
    mov dl, lf
    int dosfunc 

; y := y + 1
    inc y
    jmp while01

endwhile01:

; return -- to DOS
    mov ah, ret2dos
    int dosfunc
main    endp
    end main

Upvotes: 1

Views: 205

Answers (2)

lurker
lurker

Reputation: 58324

If dispstr is DOS function 09h then it requires the pointer to a string in memory where that string is terminated by a dollar sign ($). You can't just load offset ' ' or offset '0' into dx, as x86 assembly doesn't implicity generate an address which points to a string. Instead, it's going to take the ASCII value of ' ' or '0' and load that as an address, which points at some odd place in memory, and thus the strange output you're seeing.

If you want to print a single character, you should just use DOS function 02h:

mov ah, wrchr
mov dl, '0'
int dosfunc

This sequence also looks suspicious. It's not clear that the DOS interrupt 21h will preserve the value of ah:

mov ah, wrchr
mov dl, cr
int dosfunc
mov dl, lf
int dosfunc 

So it would be safer to reload it:

mov ah, wrchr
mov dl, cr
int dosfunc
mov ah, wrchr
mov dl, lf
int dosfunc 

Upvotes: 0

rkhb
rkhb

Reputation: 14409

mov dx, offset '0' and mov dx, offset ' ' don't produce a string nor an offset to a string. TASM replaces '0' just with the ASCII code (30h), so the instruction will be mov dx, 30h and at DS:0030h is no '0'.

I don't know const.inc. I guess there are defines like:

dosfunc = 21h
ret2dos = 4Ch
dispstr = 09h
wrchr = 02h
cr = 0Dh
lf = 0Ah

The MSDOS function Int 21h / AH=09h (mov ah, dispstr; int dosfunc) expects in DX the offset to an ASCII string which is '$'-terminated. Don't forget the '$', else the output won't stop!

Insert into the .data section:

zero db '0$'
space db ' $'

Change

mov dx, offset '0'

to

mov dx, offset zero

and

mov dx, offset ' '

to

mov dx, offset space

Upvotes: 2

Related Questions