News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Simple assembly exercise

Started by nunos, January 21, 2010, 12:25:16 PM

Previous topic - Next topic

nunos

Given the procedure "TAB proto AR_ptr: ptr real4, n: DWORD", I would like to be able to compute f(x) = ( x^2 + 3 ) / 5 for the first n terms of f(x) and store them in AR_ptr

What I have been able to do so far is this:



.data?

v1 real4 ?
X real4 ?
Y real4 ?
num dword 5
k dword ?
tmp real4 ?


.code

TAB proc AR_ptr: ptr real4, n: DWORD

    mov ecx, 0

    .REPEAT

mov X, ecx

fld X
fmul X
mov k, 3
fmul k
mov k, 5
fdiv k
fstp tmp

mov [v1+4*ecx], tmp

inc ecx

.UNTIL ( ecx == n )

ret

TAB endp






(I am not sure if it would be better if X and Y were a local variable.)

This is now working (yet), so that's why I am asking for your help. If you notice anything on the code that could been improved, please mention in your reply.



Thanks.

qWord

here my suggestion
TAB proc AR_ptr: ptr real4, n: DWORD

    .data
        num REAL4 5.0
        k   REAL4 3.0
    .code

   xor ecx,ecx
   mov edx,AR_ptr
   assume edx: ptr REAL4
 
   fld num
   fld k
   fld1                     ; used for increasing x
   fldz                     ; initialize x to zero
   .while ecx < n   
        fld st(0)           ; load x
        fmul st(0),st(1)    ; x^2
        fadd st(0),st(3)    ; x^2+k         
        fdiv st(0),st(4)    ; (x^2+k)/num
        fstp [edx+ecx*4]    ; store REAL4 into array
        fadd st(0),st(1)    ; inc x
        lea ecx,[ecx+1]
    .endw
    ffree st(0)
    ffree st(1)
    ffree st(2)
    ffree st(3)
    fincstp
    fincstp
    fincstp
    fincstp
    ret
   
TAB endp
FPU in a trice: SmplMath
It's that simple!

nunos

Thanks for your suggestion. It does work. In the meanwhile, I was working on this and almost solved the problem.

What I still can't figure out, even after went through your solution, is how to store the values in the array. fstp [edx+ecx*4] always assemble with error A2023: intruction operand must have size. I have no idea why this happens.

Btw, is [edx+ecx*4] equal to [edx+4*ecx] ?



.data

v1 real4 ?

.code   

TAB proto AR_ptr: ptr real4, n: DWORD

TAB proc AR_ptr: ptr real4, n: DWORD

    LOCAL x: dword, k: dword

    ; f(x) = (x^2 + 3) / 5

    finit               ; clear fpu

    mov ecx, 0 ; i
    mov eax, n ; total
    mov edx, AR_ptr

    .WHILE (ecx <= n)

    mov x, ecx
   
    fild x              ; x
    fimul x             ; x^2
    mov k, 3
    fiadd k             ; x^2 + 3
    mov k, 5
    fild k
    fdiv                ; (x^2 + 3) / 5
    fstp [edx+ecx*4]

    inc ecx

    .ENDW
   
    ret

TAB endp

main: 

    invoke TAB, addr v1, 5
    exit

end main





Thanks.


Ficko

Quote
error A2023: intruction operand must have size

It's usually means the instruction can be used with different sizes so you have to provide a size ptr. -fstp real4 ptr [edx+ecx*4] -

qWord

Quote from: nunos on January 21, 2010, 02:49:35 PMfstp [edx+ecx*4] always assemble with error A2023: intruction operand must have size. I have no idea why this happens.
I've used ASSUME  to say masm that edx points to an REAL4. How ever,  you can write 'fstp REAL4 ptr [edx+ecx*4]'.

Your code doesn't balance the fpu-stack, which will cause an stack overflow: your are pushing (fild) two values each pass, but only popping one value (stp).
In terms of speed its not an good idea to reload constants in each pass of your loop - try to keep as much in fpu-registers as possible. An other optimation is to replace the division by an multiplication with 1/5 = 0.2 .

Quote from: nunos on January 21, 2010, 02:49:35 PM
Btw, is [edx+ecx*4] equal to [edx+4*ecx] ?
Yes, it is. The multiplication have an higher priority than addition.
FPU in a trice: SmplMath
It's that simple!

nunos