IBM PC 8087 FPU, 66 82 바이트
계산에는 IBM PC의 Intel 8087 수학 보조 프로세서 만 사용합니다.
오프라인으로 사용해보십시오! (DOSBox 등). 오래된 PC의 지루한 8087 칩에 80 년대에 사용했던 Lotus 1-2-3 스프레드 시트 이외의 다른 작업을 수행하십시오.
9bdf 0783 c302 499b de07 83c3 0249 e342 9bde 2783 c302 49e3 399b de0f 83c3 0249
e330 9bde 3783 c302 49e3 2751 8b0f 9bd9 e883 f900 7413 9c7f 02f7 d99b d8c9 e2fb
9d7d 069b d9e8 9bd8 f159 83c3 0249 e302 ebb5 c3
언 골프 (조립되지 않은) :
START:
; RUN TESTS
MOV BX, OFFSET TST ; 5, 12, 23, 2, 4, 4, 2, 6, 7
MOV CX, CTST ; input array length
CALL WOMI ; calculate sequence
CALL PRINT_FLT ; output to console
MOV BX, OFFSET TST1 ; 5, 12, 23, 2, 4, -4, 2, 6, 7
MOV CX, CTST1
CALL WOMI
CALL PRINT_FLT
MOV BX, OFFSET TST2 ; -8, 50, 3, 3, -123, 4, 17, 99, 13
MOV CX, CTST2
CALL WOMI
CALL PRINT_FLT
MOV BX, OFFSET TST3 ; 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
MOV CX, CTST3
CALL WOMI
CALL PRINT_FLT
MOV BX, OFFSET TST4 ; 1,0,1,0,1,0
MOV CX, CTST4
CALL WOMI
CALL PRINT_FLT
MOV BX, OFFSET TST5 ; -9, -8, -1
MOV CX, CTST5
CALL WOMI
CALL PRINT_FLT
MOV BX, OFFSET TST6 ; 0, -3
MOV CX, CTST6
CALL WOMI
CALL PRINT_FLT
MOV AX, 4C00H ; exit to DOS
INT 21H
; TEST DATA
TST DW 5, 12, 23, 2, 4, 4, 2, 6, 7
CTST EQU ($-TST)/(SIZE TST) ; count of items on list
TST1 DW 5, 12, 23, 2, 4, -4, 2, 6, 7
CTST1 EQU ($-TST1)/(SIZE TST1) ; count of items on list
TST2 DW -8, 50, 3, 3, -123, 4, 17, 99, 13
CTST2 EQU ($-TST2)/(SIZE TST2) ; count of items on list
TST3 DW 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
CTST3 EQU ($-TST3)/(SIZE TST3) ; count of items on list
TST4 DW 1,0,1,0,1,0
CTST4 EQU ($-TST4)/(SIZE TST4) ; count of items on list
TST5 DW -9, -8, -1
CTST5 EQU ($-TST5)/(SIZE TST5) ; count of items on list
TST6 DW 0, -3
CTST6 EQU ($-TST6)/(SIZE TST6) ; count of items on list
; 8087 exponent: ST(0) = ST(0) ^ EXP
FIEXP MACRO EXP
LOCAL REPEAT, DONE
PUSH CX
MOV CX, EXP ; Exponent is count for loop
FLD1 ; load 1 into ST
CMP CX, 0 ; is exponent pos, neg or 0?
JZ DONE ; exit (with value 1) if exponent is 0
PUSHF ; save result flags for later
JG REPEAT ; if exp > 1 start calculation
NEG CX ; make exponent positive for loop
REPEAT:
FMUL ST(0), ST(1) ; multiply ST0 = ST0 * ST1
LOOP REPEAT
POPF ; retrieve flags from earlier
JGE DONE ; if exponent was negative, divide 1 by result
FLD1 ; push 1 into numerator
FDIV ST(0), ST(1) ; ST0 = 1 / ST1
DONE:
POP CX
ENDM
; Function WOMI: (Weapons of Math Instruction)
; input: BX - address of start of input array
; CX - length of input array
; output: ST - result on top of 8087 register stack
WOMI PROC
FILD WORD PTR [BX] ; load first item
ADD BX, 2 ; move to next
DEC CX
CALC:
FIADD WORD PTR [BX] ; add
ADD BX, 2 ; move to next
DEC CX ; decrement counter
JCXZ OUTPUT ; check if done
FISUB WORD PTR [BX] ; subtract
ADD BX, 2
DEC CX
JCXZ OUTPUT
FIMUL WORD PTR [BX] ; multiply
ADD BX, 2
DEC CX
JCXZ OUTPUT
FIDIV WORD PTR [BX] ; divide
ADD BX, 2
DEC CX
JCXZ OUTPUT
FIEXP [BX] ; exponent
ADD BX, 2
DEC CX
JCXZ OUTPUT
JMP CALC ; start again
OUTPUT:
RET
WOMI ENDP
PRINT_FLT PROC
; print top of 8087 stack
; scaling: 14 digits, 4 decimal places
; input: BX = address of a TBYTE (BCD) output buffer
; ST = value to display on top of 8087 stack
LEA BX, BUFF ; set BX to BCD output buffer
MOV AH, 2
MOV WORD PTR[BX], 10000 ; ten thousand (scale factor)
FIMUL WORD PTR[BX] ; scale up by 10000
FBSTP TBYTE PTR[BX] ; store as BCD
FWAIT ; sync 8088 and 8087
TEST BYTE PTR[BX+9], 80H ; check sign bit
JE PF_1 ; 0, goto PF_1
MOV DL, '-' ; output '-'
INT 21H
PF_1:
ADD BX, 8 ; point to high byte
MOV CH, 7 ; 14 digits before decimal point
MOV CL, 4 ; 4 shifts (8 bytes / 2 = 4 = 1 nibble)
MOV DH, 2 ; 2 times (8 bytes / 4)
PF_LOOP:
MOV DL, [BX] ; get BCD digits
SHR DL, CL ; move high digit to low nibble
OR DL, 30H ; convert to ASCII
INT 21H
MOV DL, [BX] ; get byte again
AND DL, 0FH ; mask out high digit
OR DL, 30H ; convert to ASCII
INT 21H ; output
DEC BX ; next byte
DEC CH ; decrement byte
JG PF_LOOP ; repeat if more bytes
DEC DH ; second time?
JE PF_DONE ; yes, done
MOV DL, '.' ; no, output decimal point
INT 21H
MOV CH, 2 ; 4 more digits after decimal point
JMP PF_LOOP ; go print digits
PF_DONE:
MOV DL, 0DH ; display newline CRLF
MOV AH, 2
INT 21H
MOV DL, 0AH
INT 21H
RET
PRINT_FLT ENDP
BUFF DT 0 ; output buffer for floating point digit string
_TEXT ENDS
END START
산출:
A>WOMI.COM
00000000000539.0000
-00000000000027.9136
-00000000001055.3569
00000000000256.0000
00000000000001.0000
-00000000000016.0000
-00000000000003.0000
입력은 PROC (x86은 함수와 가장 유사)를 통해 이루어지며, BX는 메모리에있는 WORD 배열에 대한 포인터이고 CX는 항목 수이며 ST에 결과를 반환합니다.
* 참고 : 함수의 실제 코드는 6682 바이트 물론 콘솔에 부동 소수점 숫자를 쓰는 코드 (요리 코드)는 83 바이트입니다. 테스트 프로그램 및 데이터는183215 바이트, .COM 실행 파일 만들기 305 총 380 바이트