如何通过使用FSQRT来打印非综合部分?

问题描述 投票:0回答:1
我不明白如何使用float号码的FSQRT,也不了解如何将此数字转换为在屏幕上显示。

.data valor dword 49 .code fild dword ptr [valor] fsqrt fistp dword ptr [valor] mov ax,word ptr valor

返回7,没关系; SQRT(49)=7.
但是有了FLD,它不知道如何获得价值。

fld dword ptr [valor] fsqrt fstp dword ptr [valor] mov ax,word ptr valor

它没有返回7,而是一些数字463365205。 我如何获得正确的价值?
    


49的平方根是一个整数(7),因此使用

fild
assembly floating-point x86-16 number-formatting x87
1个回答
0
投票
integer

编号49,并在

integer
数字7上使用fistp是正确的。尝试使用
fld
fstp无法工作,因为
fld
期望找到一个
real
编号49,并且
fstp
将结果将结果存储为real编号。
对于输入,这仅仅是提供不同的数字的问题。而不是
valor dword 49,而是编写valor dword 49.0

valor REAL4 49.0

(取决于汇编器)。
对于输出,当您不希望使用
printf
之类的产品时,您将必须自己将单个精度浮动转换为可读的文本。如果您想完整地完成此操作,那么您将面临分析754
格式的巨大任务。另一方面,如果您对用4个小数位置(示例themy the Imply thind this Direction提示)打印较小的数字感到满意,则我在下面提供的解决方案很好。
其他评论
提到不可用32位寄存器(16位窗口),因此我将提供全部8086/8087解决方案。
为了到达4个小数位置,我首先将数字乘以10000,而该数字仍在浮点堆栈上。然后将存储到内存的DWORD整数通常会自动被舍入到最接近的位置。将INT与FRAC分开只是10000执行常规整数部门的问题。DX中的分数将在0-9999中的范围内。
sqrt(7)=2.6457
下表清楚地表明,正确的四舍五入到最近发生:


ST0

ST0_FOUR

ST0_FULL


SQRT(0)
0.00000.0SQRT(1)1.0000 1.0sqrt(54)=7.34841.03.32193.3219280948873623471.44271.4426950408889634073.14163.1415926535897932380.30100.30102999566398119520.69310.69314718055994530940.00000.0
SQRT(2) 1.4142 1.414213562373095048
SQRT(7) 2.6458 2.645751311064590590
SQRT(54) 7.3485 7.348469228349534294
SQRT(32765) 181.0110 181.0110493864946356
SQRT(32766) 181.0138 181.0138116277318767
SQRT(32767) 181.0166 181.0165738268184104
1.0000
fistp

; ------------------------------ ; On input: ST0 is [-32767.9999,32767.9999] ; BX is address to store the string ; On output: ST0 is removed from the floating point stack ; IN (bx,ST0) OUT (ax,TOS) MOD (dx) ST0_FOUR: push bx si di bp ; (1) mov si, 10 ; CONST sub sp, si ; Allocate local 10-byte buffer mov bp, sp mov word [bp], 10000 fimul word [bp] fistp dword [bp+2] mov ax, [bp+2] ; DX:AX is int(ST0 * 10000) mov dx, [bp+4] ; Support for negative values test dx, dx ; Sign is in bit 15 of high word jns .a neg dx ; Negate DX:AX neg ax sbb dx, 0 mov byte [bx], '-' ; No need to store the sign locally first inc bx ; Split up between integer and fraction .a: div word [bp] ; -> AX is INT, DX is FRAC push ax ; (2) ; Working backwards, convert the 4-digit fraction first mov ax, dx ; FRAC mov di, 9 ; Offset in buffer .b: xor dx, dx div si mov [bp+di], dl ; Remainder [0,9] dec di cmp di, 5 ; Always does 4 digits ja .b ; Mandatory decimal point between INT and FRAC mov byte [bp+di], '.'-'0' ; Still working backwards, convert the integer part pop ax ; (2) .c: xor dx, dx div si dec di mov [bp+di], dl ; Remainder [0,9] test ax, ax jnz .c ; Copy to the final string, while converting to ASCII .d: mov al, [bp+di] inc di add al, '0' ; {-2,[0,9]} -> {'.',['0','9']} mov [bx], al inc bx cmp di, si jb .d ; Restore registers and return number of characters mov ax, bx add sp, si ; Release local 10-byte buffer pop bp di si bx ; (1) sub ax, bx ; -> AX is length of the whole string ret ; ------------------------------

fld1

fldl2t

fldl2e

fldpi

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.