7

I am looking for some preprocessor functionality in nasm that would allow having one source code for both x86 and x64 architectures.

I mean something in the vein of ifdef some_constant. Like C preprocessor uses if it wants to detect say if it's compiled on Windows or Linux.

Edit

I know about nasm flags. I use them. I just want to have the very same source code and expect preprocessor to handle it correctly based on those flags. I'd use ifdef ... else for stack operations and so one, having the core code same for both architectures.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
infoholic_anonymous
  • 969
  • 3
  • 12
  • 34
  • The architectures are two different for that. You won't be able to take advantage of extra registers, and so on. Stick to 32-bit code, or consider a compiled but sufficiently low level language like C. – Seva Alekseyev Jun 09 '14 at 16:28
  • It's determined by the flags in the executable format, so you can't have both architectures at the same time – phuclv Jun 09 '14 at 16:39

4 Answers4

4

__OUTPUT_FORMAT__

http://www.nasm.us/doc/nasmdoc4.html#section-4.12.6

The __OUTPUT_FORMAT__ standard macro holds the current Output Format, as given by the -f option or NASM's default. Type nasm -hf for a list.

%ifidn __OUTPUT_FORMAT__, win32 
  %define NEWLINE 13, 10 
%elifidn __OUTPUT_FORMAT__, elf32 
 %define NEWLINE 10 
%endif
Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
2

NASM cannot detect the architecture, but you can use the output format (command line option: -felf,-felf32,-felf64,-fwin32 etc.) for your needs. Read the Friendly Manual.

rkhb
  • 14,159
  • 7
  • 32
  • 60
  • so the preprocessor cannot take advantage of these flags by having programmer use macros like ifdef x64 do_sth1 else do_sth2? – infoholic_anonymous Jun 09 '14 at 17:15
  • @infoholic_anonymous: You can build and run 32-bit programs on a x64-system. So what sense has an architecture-detection? But you can retrieve the build options (`__OUTPUT_FORMAT__`). Did you read the manual? If you build the program by script, you can retrieve the machine with `uname -m`. [Here](http://stackoverflow.com/questions/4096173/how-do-i-create-a-single-makefile-for-both-32-and-64-bit) are more hints. – rkhb Jun 09 '14 at 17:33
  • I do a really simple project and have to provide *code* for both x64 and x86. The differences are minor in my code, concerning mainly one spot where calling conventions are the issue and and things like register names. register names can be replaced by define and calling convention by few lines of ifdef. Why should I keep two files and double correct them on change? I am surprised it seems odd, it's pretty common in C source of command line programs to have some sections of code dependent of the os. – infoholic_anonymous Jun 10 '14 at 22:10
2

In the NASMX package you can find the %if BITS == 64 line in syscalls.inc. This determine wether you are using nasm 64 bits or 32 bits. Perhaps this is what you wanna know?

Agguro
  • 348
  • 3
  • 11
2

NASM allows you to freely change the code size (using the bits directive) anywhere you like, which allows you to have 16-bit or 32-bit code in an elf64, or 64-bit code in an elf32. For this reason detecting the output format is relatively wrong (fragile).

Instead you want to detect the current code size. For this purpose NASM has a standard macro called __BITS__. This means you can do %if __BITS__ = 64.

However, 32-bit code and 64-bit code typically use completely different calling conventions; and 64-bit code has more registers, wider registers and other differences (where not using the extra registers or the extra width means that the code would be extremely poor quality - far worse than compiler generated code). This means that (excluding only using it for a few small macros) attempting to support both 32-bit and 64-bit in the same code is extremely silly. You just end up with completely different code for completely different cases that are slapped into the same file for no sane reason and then separated (using preprocessor magic) to work-around the fact that it never made sense in the first place.

More sensible is to have separate files for separate cases (e.g. a src/arch/x86_32 directory and a src/arch/x86_64 directory), and in that case you can just let the build script or makefile sort it out (e.g. tell the assembler to use a different "include path").

Brendan
  • 35,656
  • 2
  • 39
  • 66