0

アセンブリで DOS プログラムを書いています。マンデルブロー集合を描こうとしています。私は今、このCコードをアセンブリで翻訳しようとしています:

double x0 = i * 3.2 / maxX - 2.1; //scaled x coordinate of pixel (-2.1, 1.1)

私はそれを次のように翻訳しました:

finit
fld     scaleX  ;contains 3.5, declared with
fimul   xCoord  ;the i coordinate
fidiv   maxX    ;maximum width (320)
fsub    offsetX ;result is scaleX * xCoord / maxX - offsetX
fstp    x0      ;store the result in x0

残念ながら、最初fldは失敗します。WD デバッガーは、それがFPU レジスターにfld格納nanされていることを教えてくれます。ST(0)なんで?私は何を間違っていますか?完全なプログラムは次のとおりです: http://pastebin.com/KDrn5aLD

.387
assume cs:cseg, ds:dseg

uint    TYPEDEF word
integer TYPEDEF word
float   TYPEDEF real4
double  TYPEDEF real8

largh   =       320     ;larghezza dello schermo
alt     =       200     ;altezza dello schermo

dseg    SEGMENT para public 'data'
maxX    integer 0
maxY    integer 0
xCoord  integer 0
yCoord  integer 0       
x0      double  0.0     ;coordinata x del pixel riscalata a (-2.1 - 1.1)
y0      double  0.0     ;coordinata y del pixel riscalata a (-2.1 - 1.1)
scaleX  double  3.2
scaleY  double  2.0     ;scala in X ed in Y delle coordinate
offsetX double  2.1
offsetY double  1.0

x       double  0.0
y       double  0.0     ;valori della serie in un determinato punto (xo, yo)
zeroConst       double  0.0     ;costante double 0.0


dseg    ENDS
cseg    SEGMENT
START:
        mov     maxX, largh
        mov     maxY, alt

        mov     xCoord, 0
forX:   cmp     xCoord, largh
        jae     finish

        ;mov    dl,69
        ;mov    ah,2
        ;int    21h     ;test loop forX

        mov     yCoord, 0
        cmp     yCoord, alt
        jae     nextX
forY:   cmp     yCoord, alt
        jnb     nextX

        ;forY code here
        finit
        fld     scaleX  ;coordinate X
        fimul   xCoord
        fidiv   maxX
        fsub    offsetX ;calcolo scala * coordinata / coordinataMax - offset
        fstp    x0


;       fld     scaleY  ;coordinate Y
;       fimul   yCoord
;       fidiv   maxY
;       fsub    offsetY ;calcolo scala * coordinata / coordinataMax - offset
;       fstp    y0
;       
;       fld     zeroConst
;       fst     x
;       fstp    y



        inc     yCoord
        jmp     forY

nextX:  inc     xCoord
        jmp     forX

finish: mov     dl, 70
        mov     ah, 2
        int     21h

        mov     ah, 4Ch ;DOS terminate opcode
        xor     al, al
        int     21h     ;DOS call       
cseg    ENDS
END     START
4

1 に答える 1

2

私が見ている問題の 1 つは、セグメントを設定dsesてポイントしていないことです。dsegDOS、アセンブラ、またはリンカではなく、.EXE プログラムに対してこれを行うのはあなたの責任です。

次のようにコードを変更します。

cseg    SEGMENT
START:
        mov     ax, dseg
        mov     ds, ax
        mov     es, ax
        mov     maxX, largh
        mov     maxY, alt
        ...

また、割り込みによってコードやデータが上書きされる可能性があるため、スタック セグメントがありません。

1 つ追加:

sseg segment stack 'stack'
  dw 2048 dup (?)
sseg ends
于 2013-01-20T11:13:01.597 に答える