在Win8 64位上运行X86程序集

时间:2015-03-12 17:41:37

标签: assembly dos tasm

我是汇编的新手,我正在尝试创建复制笛卡尔的片段(x ^ 3 + y ^ 3 - 3 * a x y = 0,其中a = 12)。我已完成代码,当我编译和链接时,我没有错误。我在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

2 个答案:

答案 0 :(得分:2)

mov dx, offset '0'mov dx, offset ' ' 生成字符串或字符串的偏移量。 TASM取代了&#39; 0&#39;只需使用ASCII码(30h),所以指令为mov dx, 30h,DS为:0030h为no&#39; 0&#39;。

我不知道const.inc。我想有定义如下:

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

MSDOS函数Int 21h / AH=09hmov ah, dispstr; int dosfunc)期望DX偏移到ASCII字符串,该字符串是&#39; $&#39; -terminated。不要忘记&#39; $&#39;否则输出不会停止!

插入.data部分:

zero db '0$'
space db ' $'

更改

mov dx, offset '0'

mov dx, offset zero

mov dx, offset ' '

mov dx, offset space

答案 1 :(得分:0)

如果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