运行 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