NASM - The Netwide Assembler
NASM Forum => Using NASM => Topic started by: nobody on December 24, 2008, 03:27:19 AM
-
Hi,
This is incomplete but works. It's a function with two qword parameters,
the first must be a number that can be represented in 2 bits (0-3) or a
-1, and the second must be a variable (see calling function below) that
contains some arbitrary number. If the first parameter is a -1, it acts
as a do nothing flag, otherwise the first parameter number is placed in
the highest 2 bits of the second parameter's high dword.
Some examples:
Input:
1st param = -1
2nd param = 256
Output: 100 (hex) ;unchanged
Input:
1st param = 1
2nd param = 256
Output: 4000000000000100
Input:
1st param = 2
2nd param = 256
Output: 8000000000000100
Input:
1st param = 3
2nd param = 256
Output: C000000000000100
The function will eventually have four parameters,
any of the first three capable of being flagged
with a -1, or having a value which will be inserted
into a reserved field in the final parameter.
Be aware that Fortran, unlike C, passes the addresses
of all function arguments.
My question:
A -1 is 0xFFFFFFFFFFFFFFFF. Since I must test for
it two more times, is there a nicer way to do it?
Michael
================================
global setdir_
section .text ;
setdir_:
push ebp
mov ebp, esp
mov eax, [ebp+8]
mov edx, [ebp+12]
pop ebp
cmp dword [eax], 0xffffffff ;if both [eax] & [eax+4] are all 1s goto chngid
jne .chngid
cmp dword [eax+4], 0xffffffff
je .done
.chngid:
and dword [edx+4], 0x3fffffff ;
mov ecx, [eax]
shl ecx, 30
or [edx+4], ecx
.done:
ret
Fortran calling program:
integer m
m = 256
call setdir(3,m)
print 5, m
5 format(z20)
end
-
Hi Michael,
Question on the specification. The 1st parameter must be 0..3 or -1. What do you want to do if it isn't?
If anything over 3 is considered the "do nothing" flag...
global setdir_
section .text ;
setdir_:
push ebp
mov ebp, esp
mov eax, [ebp+8]
mov edx, [ebp+12]
pop ebp
mov ecx, [eax]
cmp ecx, 3
ja .done
and dword [edx+4], 0x3fffffff ;
shl ecx, 30
or [edx+4], ecx
.done:
ret
If the first parameter is guaranteed to be 0..3 or -1, we can do better. "shl" puts the "evicted" bit in the carry flag, so it'll be "nc" if 0..3 and "c" if -1... or if that bit happens to be set in some "invalid" value. If that helps, do it before the "and" of course. With multiple parameters, shifted different amounts, this probably isn't going to help.
If we really need to check the high dword of the first parameter before we're sure it's a "do nothing flag"... the way you're doing it may be best.
Hmmm... this is the first time I've had any success with Fortran. I tried the example you posted a while ago, and gfortran just yelled at me. ("Unclassifiable Statement" and such, IIRC - a lot of it). This one compiles... or seems to. However... it seems to print "100" no matter what the first parameter is! (using both your original subroutine and my "improved" version). So consider all of the above speculative and unproven! More research required!
Later,
Frank
-
Looks like my gfortran only likes 32-bit "integers"(?). Do I need to do something "special" to tell it 64-bit integers? (doesn't like "long long"). I'm lost, I'm afraid...
Best,
Frank
-
Hi Frank,
Sorry, I probably should have included the Makefile:
callsetdir: callsetdir.o setdir.o
gfortran callsetdir.o setdir.o -o callsetdir
callsetdir.o: callsetdir.f
gfortran -c -fdefault-integer-8 -fdefault-real-8 -fno-range-check callsetdir.f -o callsetdir.o
setdir.o: setdir.asm
nasm -f elf setdir.asm -o setdir.o
By default all integers and reals (C ints & floats) are 64-bit. Addresses are still 32-bit. The no-range-check flag keeps the compiler from griping about integers bigger than will fit in 32-bits.
As I noted in my original post, Fortran passes all function arguments by reference. i.e., you're not getting copies of the values of the parameters (ala C) on the stack but the actual machine addresses (32-bit in this case) of the parameters. It took a bit of getting used to.
Oh, and I almost forgot. Your question about passing a value not equal to -1, 1, 2, or 3 is a valid one. Actually, the first parameter can also be a 0 though that won't change the code. All the values (-1, 0, 1, 2, 3) are passed as literal integer constants, not variables, so they will never be anything else.
Merry Christmas!
Michael