NASM - The Netwide Assembler
NASM Forum => Using NASM => Topic started by: nobody on November 29, 2008, 03:42:51 PM
-
This is a mod of my earlier post.
I'm running on 32-bit Fedora 9 Linux, programming an app that requires 64-bit ints and floats.
I changed both maxofthree.asm and callmaxofthree.c (see below) to use use 64-bit args but got this nasm compilation listing:
[michael@localhost ~]$ !na
nasm -f elf maxofthree.asm -o maxofthree.o
maxofthree.asm:16: error: invalid operands in non-64-bit mode
maxofthree.asm:17: error: invalid operands in non-64-bit mode
maxofthree.asm:18: error: invalid operands in non-64-bit mode
maxofthree.asm:19: error: invalid operands in non-64-bit mode
maxofthree.asm:20: error: invalid operands in non-64-bit mode
maxofthree.asm:21: error: invalid operands in non-64-bit mode
maxofthree.asm:22: error: invalid operands in non-64-bit mode
[michael@localhost ~]$
Looked in the nasm docs and found the 64 BIT directive but wasn't sure about its placement. In any case, rather than fix the problem, it told me that 64 BIT wasn't supported for elf. Time to surrender, or am I missing something?
Michael
========================================
* callmaxofthree.c
*
* Illustrates how to call the maxofthree function we wrote in assembly
* language.
*/
#include
long long int maxofthree(long long int, long long int, long long int);
int main() {
printf("%ll\n", maxofthree(1LL, -4LL, -7LL));
printf("%ll\n", maxofthree(2LL, -6LL, 1LL));
printf("%ll\n", maxofthree(2LL, 3LL, 1LL));
printf("%ll\n", maxofthree(-2LL, 4LL, 3LL));
printf("%ll\n", maxofthree(2LL, -6LL, 5LL));
printf("%ll\n", maxofthree(2LL, 4LL, 6LL));
return 0;
}
; ----------------------------------------------------------------------------
; maxofthree.asm
;
; NASM implementation of a function that returns the maximum value of its
; three long long integer parameters. The function has prototype:
;
; long long int maxofthree(long long int x, long long int y, long long int z)
;
; Note that only rax, rcx, and rdx were used so no registers had to be saved
; and restored.
; ----------------------------------------------------------------------------
global maxofthree
section .text
maxofthree:
mov rax, [esp+4]
mov rcx, [esp+8]
mov rdx, [esp+12]
cmp rax, rcx ;if rax < rcx
cmovl rax, rcx ; rax <- rcx
cmp rax, rdx ;if rax < rdx
cmovl rax, rdx ; rax <- rdx
ret
-
The flag '-f elf' defaults to 32-bit code. Use the '-f elf64' flag to parse 64-bit source.
After making that correction, you will need to install 64-bit Fedora 9 Linux in order to test the program.
Nathan.
-
Thanks for the info.
I have 64-bit Fedora 10 on it's way to me, but I was hoping to be able to use 64-bit numbers with 32-bit pointers, as I now do in C. You're telling me that if I want to use 64-bit numbers with nasm I must have the 64-bit OS and the 64-bit pointers that go with it. Is that correct?
Michael
-
Hi Michael... Hi Nathan,
Yeah, "-f elf64"... and a 64-bit OS... and, worse, I don't think the parameters are going to be on the stack - not at esp + 4, 8, 12 anyway. Have a look at:
http://www.x86-64.org/documentation/abi-0.99.pdf (http://www.x86-64.org/documentation/abi-0.99.pdf)
for parameter-passing conventions (and much, much more). Looks like a royal PITA to me!
However... just having read your latest, Michael... yeah, you should be able to use 64-bit numbers in 32-bit code - passing pointers to the numbers, rather than the numbers themselves. I *think* I know how to do the asm part of this, but I'm shakey on the C part... particularly how we return the answer. Lemme look at the C part of your code - disassemble it and see what C seems to be expecting... Maybe we can figure this out...
Later,
Frank
-
Yeah, that does it. I was beginning to think I had a defective processor.
On to "real" problems.
Thanks!
Michael
[michael@localhost ~]$ gcc -c callmaxoftwo.c -o callmaxoftwo.o
[michael@localhost ~]$ gcc callmaxoftwo.o maxoftwo.o -o callmaxoftwo
[michael@localhost ~]$ ./callmaxoftwo
2
3
4
2
3
4
400000000000
[michael@localhost ~]$