Recent Posts

Pages: [1] 2 3 ... 10
1
The Campus / Re: Help with accessing the data in Tag Word register
« Last post by aw27 on Today at 05:13:25 PM »
Quote
I just want to utilize fnstenv/fstenv to view the TAG WORD register values to diagnose some issues, I understand its functions based on the Intel manual.
I would read instead the Raymond tutorial:idea:
2
I need to ask him something but don't have a current email address.
3
The Campus / Re: Help with accessing the data in Tag Word register
« Last post by Chris. on Today at 11:38:01 AM »
It was just a leftover because I suspected that maybe the 1#IND was caused by loading data into an occupied register.
you can disregard any fincstp and fdecstp instructions, They were only for experimenting.

I have it repeating intentionally just to test things.

Very early on when I very first started messing with the FPU I found out it works similarly to my HP-32s RPN calculator that was given to me, with minor differences.

It should always divide the $samplevalue by 2, instead I get 1#IND when I want to load 2 on 2nd loop.

And now would be a good time to understand how to use the TAG WORD register.
4
The Campus / Re: Help with accessing the data in Tag Word register
« Last post by raymond on Today at 10:51:56 AM »
Quote
So i am unable to push the 32-bit base pointer? correct?

WRONG. The "Access violation writing location 0x00401008" message only means that your program is trying to write data in the code section because of the instruction at 0x0040105F. This is definitely not allowable. According to what you are reporting, the ESI register somehow seems to have been containing that 0x00401008 address where you instructed the fpu to store the environment.

Then, you have the fincstp instruction just before the jne $repeat instruction.

Could you explain what you were attempting to do with that fincstp instruction.

In your case, its effect would be to bring about empty fpu registers as the top register which you would then try to use with other instructions. This is definitely not allowable either. You will have to learn carefully how to use the fpu and control the content of its registers before expecting to be successful in programming it. READ THE TUTORIAL.

BTW, if you read the description of the fincstp instruction, it has absolutely no effect on the ZERO flag. Assuming you wouldn't have any exception thrown at you, your program would never have ended. And, you would always have loaded the same value from the $Tvalueinc[ecx] array by not modifying the ECX register.
5
ASMC Development / Re: Large integers and floats
« Last post by nidud on Today at 10:11:54 AM »
Some more __float128 stuff.

The mantissa in a quad is 113 bit where only 112 is stored. To apply math this has to be expanded to 128, in RDX:RAX in this case, where the high bit and 15 low bits are shifted out and the rest stored in the end.

Code: [Select]
    mov rax,[r8] ; low 48-bit
    shl rax,16 ;
    mov rdx,[r8+6] ; high 64-bit
    mov cx,[r8+14]
    and cx,0x7FFF ; bit 112 set if not zero
    neg cx
    rcr rdx,1 ; 113 bits..
    rcr rax,1

Here's a test version for adding and subtracting two REAL16 numbers. This is similar to the REAL10 version using a 64-bit mantissa in EDX:EAX.

Code: [Select]
include math.inc

option win64:rsp nosave noauto

.code

_subfq proc result:ptr, a:ptr, b:ptr

    mov r9d,0x80000000
    jmp _lk_add

_subfq endp

_addfq proc result:ptr, a:ptr, b:ptr

    xor r9d,r9d

_addfq endp

_lk_add proc private uses rsi rdi rbx result:ptr, a:ptr, b:ptr, sign:dword
    ;
    ; quad float [rcx] = quad float [rdx] +- quad float [r8]
    ;
    mov r10,rcx ; save dest.

    mov rbx,[r8]
    shl rbx,16
    mov rdi,[r8+6]
    mov si,[r8+14]
    and si,0x7FFF
    neg si
    mov si,[r8+14]
    rcr rdi,1
    rcr rbx,1
    shl esi,16
    mov r8,rdx
    mov rdx,[r8+6]
    mov rax,[r8]
    shl rax,16
    mov si,[r8+14]
    and si,0x7FFF
    neg si
    mov si,[r8+14]
    rcr rdx,1
    rcr rax,1

    .repeat             ; create frame -- no loop

        add si,1            ; add 1 to exponent
        jc  er_NaN_A        ; quit if NaN
        jo  er_NaN_A        ; ...
        add esi,0xFFFF      ; readjust low exponent and inc high word
        jc  er_NaN_B        ; quit if NaN
        jo  er_NaN_B        ; ...
        sub esi,0x10000     ; readjust high exponent
        xor esi,r9d         ; flip sign if subtract

        .if !rax && !rdx    ; A is 0 ?
            shl si,1        ; place sign in carry
            .ifz
                shr esi,16
                mov rax,rbx     ; return B
                mov rdx,rdi
                shl esi,1
                or  rbx,rdi     ; check for 0
                or  bx,si
                .ifnz           ; if not zero
                    shr esi,1   ; -> restore sign bit
                .endif
                .break
            .endif
            rcr si,1        ; put back the sign
        .endif
        .if !rbx && !rdi    ; B is 0 ?
            .break .if !(esi & 0x7FFF0000)
        .endif

        mov ecx,esi         ; exponent and sign of A into ECX
        rol esi,16          ; shift to top
        sar esi,16          ; duplicate sign
        sar ecx,16          ; ...
        and esi,0x80007FFF  ; isolate signs and exponent
        and ecx,0x80007FFF  ; ...
        mov r9d,ecx         ; assume A < B
        rol esi,16          ; rotate signs to bottom
        rol ecx,16          ; ...
        add cx,si           ; calc sign of result
        rol esi,16          ; rotate signs to top
        rol ecx,16          ; ...
        sub cx,si           ; calculate difference in exponents
        .ifnz               ; if different
            .ifc                ; if B < A
                mov r9d,esi     ; get larger exponent for result
                neg cx          ; negate the shift count
                xchg rbx,rax    ; flip operands
                xchg rdi,rdx
            .endif
            .if cx > 128        ; if shift count too big
                mov esi,r9d
                shl esi,1       ; get sign
                rcr si,1        ; merge with exponent
                mov rax,rbx     ; get result
                mov rdx,rdi
                .break
            .endif
        .endif

        mov esi,r9d
        mov ch,0            ; zero extend B
        or  ecx,ecx         ; get bit 0 of sign word - value is 0 if
                            ; both operands have same sign, 1 if not
        .ifs                ; if signs are different
            mov ch,-1       ; - set high part to ones
            neg rdi         ; - negate the fraction of B
            neg rbx
            sbb rdi,0
            xor esi,0x80000000 ; - flip sign
        .endif

        xor r11,r11         ; get a zero for sticky bits
        .if cl              ; if shifting required
            .if cl >= 64        ; if shift count >= 64
                .if rax         ; check low order qword for 1 bits
                    inc r11     ; r11=1 if RAX non zero
                .endif
                .if cl == 128   ; if shift count is 128
                    or  r11,rdx ; get rest of sticky bits from high part
                    xor rdx,rdx ; zero high part
                .endif
                mov rax,rdx     ; shift right 64
                xor rdx,rdx
            .endif
            xor  r8,r8
            shrd r8,rax,cl      ; get the extra sticky bits
            or   r11,r8         ; save them
            shrd rax,rdx,cl     ; align the fractions
            shr  rdx,cl
        .endif

        add rax,rbx
        adc rdx,rdi
        adc ch,0
        .ifs
            .if cl == 128
                xor r8b,r8b
                mov r9,0x7FFFFFFFFFFFFFFF
                .if r11 & r9
                    inc r8b     ; make single sticky bit
                .endif
                shr r8b,1
                adc rax,0       ; round up fraction if required
                adc rdx,0
            .endif
            neg rdx
            neg rax
            sbb rdx,0
            mov ch,0
            xor esi,0x80000000
        .endif

        .if rax || rdx || ch
            .if !si
                add esi,esi
                rcr si,1
                .break
            .endif
            ;
            ; if top bits are 0
            ;
            .if !ch
                rol r11,1   ; set carry from last sticky bit
                rol r11,1
                .repeat
                    dec si  ; decrement exponent
                    .ifz
                        add esi,esi
                        rcr si,1
                        .break(1)
                    .endif
                    adc rax,rax ; shift fraction left one bit
                    adc rdx,rdx
                .untilb         ; until carry
            .endif
            inc si
            cmp si,0x7FFF
            je  overflow
            stc                 ; set carry
            rcr rdx,1           ; shift fraction right 1
            rcr rax,1
            bt  eax,15
            .ifc                ; if guard bit is on
                shl r11,1       ; get top sticky bit
                .ifz            ; if no more sticky bits
                    ror rax,1   ; set carry with bottom bit of DX
                    rol rax,1
                .endif
                adc rax,0       ; round up fraction if required
                adc rdx,0
                .ifc            ; if we got a carry
                    rcr rdx,1   ; shift fraction right 1
                    rcr rax,1
                    inc si      ; increment exponent
                    cmp si,0x7FFF
                    je  overflow
                .endif
            .endif
        .else
            xor esi,esi
        .endif
        add esi,esi
        rcr si,1
        .break

      ; A is a NaN or infinity

      er_NaN_A:

        dec si
        add esi,0x10000
        .ifnc
            .break .ifno
        .endif
        sub esi,0x10000
        mov r11,0x8000000000000000
        .if !rax && !rbx
            .if rdx == rdi && rdx == r11
                shr rdx,2
                or  si,-1 ; -NaN - FFFF40 ?
                .break
            .endif
        .endif
        .if rdi == rdx
            cmp rbx,rax
        .endif
        jna return_B
        .break

      ; B is a NaN or infinity

      er_NaN_B:

        sub esi,0x10000
        .if !rbx
            mov rdx,0x8000000000000000
            .if rdx == rdi
                xor esi,r9d
            .endif
        .endif
      return_B:
        mov rdx,rdi
        mov rax,rbx
        shr esi,16
        .break

      overflow:
        mov si,0x7FFF
        xor rax,rax
        xor rdx,rdx

    .until 1

    shl rax,1           ; shift bits back
    rcl rdx,1
    shr rax,16          ; 16 low bits
    mov [r10],rax
    mov [r10+6],rdx
    mov [r10+14],si     ; exponent and sign
    mov rax,r10         ; return result
    ret

_lk_add endp

    end
6
The Campus / Re: Help with accessing the data in Tag Word register
« Last post by jj2007 on Today at 09:04:26 AM »
So you decided to try what happens if you do...
Code: [Select]
fstenv [esi]... without ever considering the option to let esi point to some piece of memory? And it doesn't work?  ::)

Btw your code is unreadable.
Code: [Select]
main PROC
LOCAL szBuf[9]:byte
fstcw $prevCW
fwait
fld Bval ;  [loads first instance of b]]
fmul Bval ; [b*b = b^2]
fld Aval ;[Load a (a*c)]
fmul Cval ;(a*c)
fmul _fourval ;[4*a*c]
fsubp;[b^2-4*a*c]
ftst ;compare ST(0) with 0.0
fstsw ax ;[store camparison results in ax]
fwait;wait
sahf ;transfer flags from AH register
mov ecx, 04h
jb _negative ;jump if <0
fsqrt ;sqrt(b^2-4*a*c)
jmp Finished
7
The Campus / Re: Help with accessing the data in Tag Word register
« Last post by Chris. on Today at 06:48:36 AM »
I added rest of code
This code generates "Exception thrown at 0x0040105F in Project.exe: 0xC0000005: Access violation writing location 0x00401008.

In the disassembler i searched for 0x00401008 address and found:


Code: [Select]
00401008 55                   push        ebp
So i am unable to push the 32-bit base pointer? correct?

Once you get past the exception thrown error (By removing:
Code: [Select]
fstenv [esi]
mov eax,[esi+28]
)

You will find that
Code: [Select]
fstenv [esi]
mov eax,[esi+28]

causes a #1IND in ST(0), during 2nd loop attempt, which after some research led me to attempt to understand how to view the TAG WORD in the first place.
8
The Campus / Re: Help with accessing the data in Tag Word register
« Last post by raymond on Today at 04:15:26 AM »
That partial code makes it extremely difficult to understand what you are attempting to do. However, I added comments to some of your code and you may want to explain some of the included question marks.

Quote
.386                     ;you should use .686, some instructions not being recognized by the older .386

mov ax, $prevCW
push eax
fldcw [esp]            ;can be more easily done with 'fldcw $prevCW'
fld $Tvalueinc[ecx]
fnstenv [esp]        ;overwrite 28 bytes of the stack with the 28 bytes of the environment ????
fwait
mov eax,esp         ;copy the address of the stack to EAX ????
fstsw ax               ;then overwrite the lower 16 bits of EAX with the Status Word of the fpu ?????
fdivp
FRNDINT
fst st(1)               ;overwrite the content of st(1) with the content of st(0) ?
9
The Colosseum / Re: Any news from farabi ?
« Last post by nidud on Today at 04:10:03 AM »
So, socialism creates jobs and provide free education.

The US army is the largest employer and hence the largest socialistic enterprise in the world.
10
The Campus / Re: Help with accessing the data in Tag Word register
« Last post by jj2007 on Today at 03:49:25 AM »
Your code doesn't build:
Code: [Select]
Tmp_File.asm(31) : Error A2102: Symbol not defined : $Tvalueinc
Tmp_File.asm(50) : Error A2102: Symbol not defined : squareroot
Tmp_File.asm(51) : Error A2102: Symbol not defined : squareroot
Tmp_File.asm(52) : Error A2102: Symbol not defined : squareroot
Tmp_File.asm(53) : Error A2102: Symbol not defined : $interm
Tmp_File.asm(54) : Error A2102: Symbol not defined : _title
Tmp_File.asm(54) : Error A2147: Too few arguments to INVOKE: MessageBoxA

Why don't you try to build your code successfully before posting it?
Pages: [1] 2 3 ... 10