我不明白为什么当我运行程序时只打印第一个 y 而不是 4

问题描述 投票:0回答:1

我想我在汇编程序中以某种方式错误地使用了循环。任务文字:

计算函数 Yn = 37/(2x^2+7.3) 的 4 个值(x 随着步骤 2 从 1 变化)。

这是我的程序代码:

;Розрахувати 4 значень функції Y = 37/(2x^2+7.3) (x змінюється с  шагом 2.0).

.386

.model flat, stdcall

option casemap:none

include \masm32\include\windows.inc

include \masm32\include\kernel32.inc

include \masm32\include\user32.inc

include \masm32\include\fpu.inc

includelib \masm32\lib\kernel32.lib

includelib \masm32\lib\user32.lib

includelib \masm32\lib\fpu.lib

.data       

    CrLf equ 0A0Dh   
                  
    _y1 dt 0.0 ;объявляем у1

    _y2 dt 0.0 ;объявляем у2

    _y3 dt 0.0 ;объявляем у3

    _y4 dt 0.0 ;объявляем у4

    _temp1 DWORD ? ;создаём темп

    _two DWORD 2.0 ;создаём константу с значеием 2.0

    _x DWORD 1.0 ;создаём константу с значеием 1.0

    _op1 DWORD 37.0 ;создаём константу с значеием 37.0

    _op2 DWORD 7.3 ;создаём константу с значеием 7.3

    _zero DWORD 0.0 ;создаём константу с значеием 0.0

    _step DWORD 2.0 ;создаём константу с значеием 2.0

info db "Batyuk Bogdan Stundent of KNEU",10,10,  
  
"Y = 37/(2x^2+7.3), x change with step 2.0",10,10, 

      "y1 = " 

      _res1 db 11 DUP(0),10,10

    db "y2 = "

    _res2 db 11 DUP(0),10,10

    db "y3 = "

    _res3 db 11 DUP(0),10,10

    db "y4 = "

    _res4 db 12 DUP(0),10,10

        ttl db "Calculating",0             
.code       

_start:  
        
finit 

mov ecx, 4 

m1: fld _x ;вводим в стек х

    fmul _x ;x*x=x^2

    fmul _two ;x^2*2

    fadd _op2 ;x^2*2+7.3

    fdivr _op1    ;37/x^2*2+7.3 

    fld _x ;вносим в стек х

    fadd _step ;x+step (1+2)

    fstp _x ;вивидом значеием из стека

loop m1 ;зацикливаем m1

    fstp _y4 ; 

    fstp _y3 ; 

    fstp _y2 ; 

    fstp _y1 ; 

    invoke FpuFLtoA,offset _y1,10,offset _res1,SRC1_REAL or SRC2_DIMM 

    mov word ptr _res1 + 11, CrLf

    invoke FpuFLtoA,offset _y2,10,offset _res2,SRC1_REAL or SRC2_DIMM 

    mov word ptr _res2 + 11, CrLf

    invoke FpuFLtoA,offset _y3,10,offset _res3,SRC1_REAL or SRC2_DIMM 

    mov word ptr _res3 + 11, CrLf

    invoke FpuFLtoA,offset _y4,10,offset _res4,SRC1_REAL or SRC2_DIMM 

    invoke MessageBox, 0, offset info, offset ttl, MB_ICONINFORMATION 

    invoke  ExitProcess, 0  

end _start 
assembly x86 masm masm32
1个回答
0
投票

FpuFLtoA
存储以 null 结尾的字符串,因此在第一次调用后
_res1
在末尾包含字节
0
MessageBox
显示以 null 结尾的字符串,因此它会忽略字节
0
之后的所有内容。

解决方案之一是在运行时通过复制所需的组件来组成“answer”字符串。

我修改了您程序中与结果转换相关的部分,并保留了原样的计算部分。

...
; First modified part concerns data organization in `.data` section and
; introduces `.data?` section for results:

    info db "Batyuk Bogdan Stundent of KNEU",10,10,
            "Y = 37/(2x^2+7.3), x change with step 2.0",10,10
    info_len = $ - info

    str_eq db "y0 = "       ; index "0" is updated in code
    str_eq_len = $ - str_eq

    ttl db "Calculating",0

.data?

    _res db 16 DUP(?)
    _res_len = $ - _res

    ; reserve space for answer: info + 4 results
    answer db (info_len + (str_eq_len + _res_len + 2) * 4) dup(?)

; End of first modified part

.code

_start:

    finit

    mov ecx, 4

m1: fld _x ;вводим в стек х
    fmul _x ;x*x=x^2
    fmul _two ;x^2*2
    fadd _op2 ;x^2*2+7.3
    fdivr _op1    ;37/x^2*2+7.3
    fld _x ;вносим в стек х
    fadd _step ;x+step (1+2)
    fstp _x ;вивидом значеием из стека

loop m1 ;зацикливаем m1

    fstp _y4 ;
    fstp _y3 ;
    fstp _y2 ;
    fstp _y1 ;

; Second modified part: compose answer string

    mov ebx, offset _y1         ; address of first stored answer
    mov edi, offset answer      ; store answer string here
    cld                         ; direction for string opearations: incrementing

    ; copy info string to answer
    mov esi, offset info
    mov ecx, info_len
    rep movsb

    mov ecx, 4                  ; will print 4 numbers

m2: push ecx

    ; copy "yN = " string
    mov esi, offset str_eq
    inc byte ptr [esi + 1]       ; update y index
    mov ecx, str_eq_len
    rep movsb

    ; convert result to string
    invoke FpuFLtoA, ebx, 10, edi, SRC1_REAL or SRC2_DIMM

    ; scan for end of line in converted result
    mov ecx, _res_len
    xor al,al
    repnz scasb

    pop ecx
    loop cont   ; continue if not last element

    ; show message box and exit if all elements processed
    invoke MessageBox, 0, offset answer, offset ttl, MB_ICONINFORMATION 
    invoke  ExitProcess, 0

cont:
    dec edi     ; go back for 1 char

    mov ax, CrLf
    stosw               ; store CR/LF

    add ebx, 10         ; take next stored result. extended float: 10 bytes
    jmp m2

end _start
© www.soinside.com 2019 - 2024. All rights reserved.