FASM says error: reserved word used as symbol on base 2 binary constants like 0b101 (C++ style)

0

I need to make a C++ program for an assignment that can add or subtract 1024 and 2048 bit binary numbers, and the functions that do said operations must be made in Assembly. I tried going about this by interpreting the numbers as 64-long arrays of 32 bit binary numbers and adding them one element after another, starting from the end, and writing the result into the third array. However, after making a testing version made for arrays with only 3 32 bit numbers each, I'm faced with the fact that the function doesn't respond. I tried making a version of said function that works predetermined data, but the FASM compiler says "error: reserved word used as symbol.". There isn't an answer I could find anywhere, so now I'm asking for help here.

section '.data' data readable writable

IN_NUM1 dd 0b00000100000000000000000000000000, 0b00000100000000000000000000000000, 0b00000111111111111111111111111111     ;"error: reserved word used as symbol" is here
IN_NUM2 dd 0b00000010000000000000000000000000, 0b00000010000000000000000000000000, 0b00000100000000000000000000000000
OUT_NUM dd 0b00000000000000000000000000000000, 0b00000000000000000000000000000000, 0b00000000000000000000000000000000

section '.code' code readable writable executable

start:

        mov edi, [IN_NUM1]
        mov esi, [IN_NUM2]
        mov ecx, 3
        
PUSHING:

        mov eax, [edi]
        push eax
        mov eax, [esi]
        push eax
        inc edi
        inc esi
        loop PUSHING
        
        clc
        
ADDING:

        pop eax
        pop ebx
        adc eax, ebx
        mov [OUT_NUM+ecx-1], eax
        loop ADDING
        
    ccall [printf], [OUT_NUM]
    ccall [getchar]
    stdcall [ExitProcess],0

The error message from that line in a file by itself (editor's note: from my computer, not the OP's):

flat assembler  version 1.73.24  (16384 kilobytes memory, x64)
foo.asm [1]:
IN_NUM1 dd 0b00000100000000000000000000000000, 0b00000100000000000000000000000000, 0b00000111111111111111111111111111     ;"error: reserved word used as symbol" is here
processed: IN_NUM1 dd 0b00000100000000000000000000000000,0b00000100000000000000000000000000,0b00000111111111111111111111111111
error: reserved word used as symbol.

But IN_NUM1 dd 1,2,4 assembles fine.

Author's edit: Thanks to the help of @PeterCordes, I have made good progress. However, there are still some issues. With the new code, the addition goes like this: 87654321 + 00000000, FFFFFFFF + 00000001, 04000000 + 02000000. And if I don't multiply ecx by 4, it goes "00000012 + 00000087, 00001234 + 00008765, 00123456 + 00876543". I don't get why this happens, and I would very much appreciate your help. And as for the code itself:

section '.data' data readable writable

IN_NUM1 dd 0x12345678, 0x04000000, 0xFFFFFFFF
IN_NUM2 dd 0x87654321, 0x02000000, 0x00000001
OUT_NUM dd 0x00000000, 0x00000000, 0x00000000

section '.code' code readable writable executable

start:

        mov ecx, 3
        clc
        
ADDING:

        mov eax, [IN_NUM1+ecx*4]
        mov ebx, [IN_NUM2+ecx*4]
        adc eax, ebx
        mov [OUT_NUM+ecx*4], eax
        loop ADDING
assembly
binary
x86-64
literals
fasm
asked on Stack Overflow Nov 2, 2020 by Samuel Bucher • edited Nov 2, 2020 by Peter Cordes

1 Answer

2

There's no need to use base 2 in the source code, you can just write them in hex like a normal person. Any way of writing the same number turns into the same binary bit-pattern in the assembler output. Also, you could define the arrays and their contents in C++, and pass pointers to your asm functions.

See the FASM manual, section 1.2.4 Numerical expressions (which I found by searching on the word "binary" in the manual):

The numbers in the expression are by default treated as a decimal, binary numbers should have the b letter attached at the end, octal number should end with o letter, hexadecimal numbers should begin with 0x characters (like in C language) or with the $ character (like in Pascal language) or they should end with h letter. Also quoted string, when encountered in expression, will be converted into number - the first character will become the least significant byte of number.

So it's like NASM but only supporting 101b,
not NASM's 101y or 0b101 etc. for base 2.


BTW, the first step in dealing with FASM's unhelpful error message was trying a different number syntax, to make sure something like IN_NUM1 dd 1,2,4 assembled. Since it did, that shows that the syntax for writing numbers was not what FASM wanted, rather than some other part of the syntax.


BTW, you don't need to push and pop your input. Store your data little-endian (least-significant chunk first) or loop backwards if you really want. You can increment pointers or an index without affecting FLAGS by using lea. Or inc / dec leave CF unmodified. (Older Intel CPUs (P6-family) will have performance problems in an inc / adc loop, but Skylake has no flag-merging cost at all.)

You could inc an negative index up towards zero, and index relative to the ends of the arrays, so your loop logic can be inc ecx / jnz. That's pretty good for performance if you're not going to unroll the loop, although adc reg, [reg + ecx*4] won't micro-fuse even on Skylake (will un-laminate at issue/rename because of the indexed addressing mode).

answered on Stack Overflow Nov 2, 2020 by Peter Cordes

User contributions licensed under CC BY-SA 3.0