运行 Win8 64 位 X86 程序集
Running X86 Assembly on Win8 64 bit
我是组装新手,正在尝试复制笛卡尔叶 (x^3 + y^3 - 3*axy = 0 其中 a= 12).我已经完成了代码,当我编译 link 时,我没有收到任何错误。我在 win8 64 位上通过 DOSBox 0.74 使用 TASM。但是当我尝试通过 DOSBox 执行 folium.exe 文件时,我得到了随机字符行,它说无法在随机字符的中心打开文件。我不知道为什么会这样,根据我的代码,它应该显示“0”或“”。要么我组装错误,要么我的代码中有我不知道的错误。
在 DOSBox 0.74 中,我只需键入 TASM folium.asm
,然后键入 LINK folium
,然后键入 folium
即可执行。这就是我为我的其他代码所做的方式并且它有效。
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
mov dx, offset '0'
和 mov dx, offset ' '
不 生成字符串或字符串的偏移量。 TASM 仅用 ASCII 代码 (30h) 替换“0”,因此指令将是 mov dx, 30h
并且在 DS:0030h 处没有“0”。
我不知道 const.inc
。我想有这样的定义:
dosfunc = 21h
ret2dos = 4Ch
dispstr = 09h
wrchr = 02h
cr = 0Dh
lf = 0Ah
MSDOS 函数 Int 21h / AH=09h
(mov ah, dispstr; int dosfunc
) 在 DX
中期望以 '$' 结尾的 ASCII 字符串的偏移量。不要忘记'$',否则输出不会停止!
插入 .data
部分:
zero db '0$'
space db ' $'
改变
mov dx, offset '0'
至
mov dx, offset zero
和
mov dx, offset ' '
至
mov dx, offset space
如果 dispstr
是 DOS 函数 09h
那么它需要指向内存中字符串的指针,该字符串以美元符号 ($
) 结尾。您不能只将 offset ' '
或 offset '0'
加载到 dx
中,因为 x86 程序集不会隐式生成指向字符串的地址。相反,它将采用 ' '
或 '0'
的 ASCII 值并将其作为地址加载,该地址指向内存中的某个奇怪位置,因此您看到的是奇怪的输出。
如果你想打印单个字符,你应该只使用DOS函数02h
:
mov ah, wrchr
mov dl, '0'
int dosfunc
这个序列看起来也很可疑。不清楚 DOS 中断 21h
是否会保留 ah
:
的值
mov ah, wrchr
mov dl, cr
int dosfunc
mov dl, lf
int dosfunc
所以重新加载它会更安全:
mov ah, wrchr
mov dl, cr
int dosfunc
mov ah, wrchr
mov dl, lf
int dosfunc
我是组装新手,正在尝试复制笛卡尔叶 (x^3 + y^3 - 3*axy = 0 其中 a= 12).我已经完成了代码,当我编译 link 时,我没有收到任何错误。我在 win8 64 位上通过 DOSBox 0.74 使用 TASM。但是当我尝试通过 DOSBox 执行 folium.exe 文件时,我得到了随机字符行,它说无法在随机字符的中心打开文件。我不知道为什么会这样,根据我的代码,它应该显示“0”或“”。要么我组装错误,要么我的代码中有我不知道的错误。
在 DOSBox 0.74 中,我只需键入 TASM folium.asm
,然后键入 LINK folium
,然后键入 folium
即可执行。这就是我为我的其他代码所做的方式并且它有效。
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
mov dx, offset '0'
和 mov dx, offset ' '
不 生成字符串或字符串的偏移量。 TASM 仅用 ASCII 代码 (30h) 替换“0”,因此指令将是 mov dx, 30h
并且在 DS:0030h 处没有“0”。
我不知道 const.inc
。我想有这样的定义:
dosfunc = 21h
ret2dos = 4Ch
dispstr = 09h
wrchr = 02h
cr = 0Dh
lf = 0Ah
MSDOS 函数 Int 21h / AH=09h
(mov ah, dispstr; int dosfunc
) 在 DX
中期望以 '$' 结尾的 ASCII 字符串的偏移量。不要忘记'$',否则输出不会停止!
插入 .data
部分:
zero db '0$'
space db ' $'
改变
mov dx, offset '0'
至
mov dx, offset zero
和
mov dx, offset ' '
至
mov dx, offset space
如果 dispstr
是 DOS 函数 09h
那么它需要指向内存中字符串的指针,该字符串以美元符号 ($
) 结尾。您不能只将 offset ' '
或 offset '0'
加载到 dx
中,因为 x86 程序集不会隐式生成指向字符串的地址。相反,它将采用 ' '
或 '0'
的 ASCII 值并将其作为地址加载,该地址指向内存中的某个奇怪位置,因此您看到的是奇怪的输出。
如果你想打印单个字符,你应该只使用DOS函数02h
:
mov ah, wrchr
mov dl, '0'
int dosfunc
这个序列看起来也很可疑。不清楚 DOS 中断 21h
是否会保留 ah
:
mov ah, wrchr
mov dl, cr
int dosfunc
mov dl, lf
int dosfunc
所以重新加载它会更安全:
mov ah, wrchr
mov dl, cr
int dosfunc
mov ah, wrchr
mov dl, lf
int dosfunc