.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
49的平方根是一个整数(7),因此使用
fild
编号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解决方案。
sqrt(7)=2.6457
下表清楚地表明,正确的四舍五入到最近发生:
ST0
ST0_FOUR
ST0_FULL
SQRT(0)
sqrt(54)=7.3484
1.03.32193.3219280948873623471.44271.4426950408889634073.14163.1415926535897932380.30100.30102999566398119520.69310.69314718055994530940.00000.0SQRT(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 | ||