Reputation: 365
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
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
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