Well...
segment .data
matrix dw 12, 8, 23,
19, 6, 14,
24, 18, 4,
matrix2 dw 23, 2, 12,
23, 2, 12,
23, 2, 12,
As the error message says, Nasm is expecting a label or instruction at the start of a line. Unlike C, assembler is "line oriented" and won't continue on to the next line... unless we give it the line-continuation character '\'...
segment .data
matrix dw 12, 8, 23,\
19, 6, 14,\
24, 18, 4,
or, as an alternative, put an instruction (pseudo-instruction, actually) at the start of a line...
segment .data
matrix dw 12, 8, 23,
dw 19, 6, 14,
dw 24, 18, 4,
Nasm will conveniently ignore the trailing commas, although they probably really shouldn't be there. As a third alternative, string 'em all out on one line - more readable the way you've got it.
Then... despite the fact that you're assembling to 32-bit code, you're using 16-bit registers, 16-bit instructions, and so you're stuck with 16-bit addressing modes: an optional offset, plus an optional base register (bx or bp), plus an optional index register (si or di). Two index registers is no go! In 32-bit addressing modes, any register can be a base register and any but esp can be an index register (we also get an optional scale, 1, 2, 4, or 8, to be multiplied by the index register). Also, Nasm expects the offset ("matrix") to be inside the square brackets. "mov ax, [matrix + esi + edi]" will assemble - really ought to make sure the upper bits of esi and edi are zero! Using bx for one of the registers would also work.
Then... you haven't got a valid operand on either of your "mul"s. I didn't know what the first one was supposed to do, so I commented it out. I put "ten dw 10" in the .data section and did "mul word [ten]". "mul" won't allow an immediate operand - "imul" will ("imul" is actually a couple of different instructions).
At this point, it'll assemble... but ld whines about not finding an enterypoint (it actually does the right thing). Add "global _start" and a "_start:" label... There! Silence!
It's hard to say if it "works" or not. You do the "mul" but don't do anything with the result. I suppose you're going to put it in a "result_matrix" or something...
In 32-bit code, it isn't easier, shorter, or faster to use 16-bit instructions. I'd do it all in 32-bit. If you really need to limit yourself to 16-bit numbers, okay use 16-bit registers/instructions there... but the addresses are still 32-bit!
Well, as usual, I've been too slow and Mathi has posted a better answer. Thanks Mathi!
Best,
Frank