nasm version 2.09rc1.
as per intel spec: http://www.intel.com/Assets/PDF/manual/253667.pdf page 4-319:
There is no such instruction as "push imm64" and "push imm32" is valid in 64-bit mode.
Recommend following patch (assuming I got the flags right):
diff -ur nasm-2.09rc1/insns.dat nasm-2.09rc1-patched/insns.dat
--- nasm-2.09rc1/insns.dat 2010-06-07 21:44:06.000000000 +0300
+++ nasm-2.09rc1-patched/insns.dat 2010-06-24 14:49:25.000000000 +0300
@@ -1022,8 +1022,7 @@
PUSH imm8 \1\x6A\274 186
PUSH imm16 \320\144\x68\140 186,AR0,SZ
PUSH imm32 \321\154\x68\150 386,NOLONG,AR0,SZ
-PUSH imm32 \321\154\x68\150 386,NOLONG,SD
-PUSH imm64 \323\154\x68\250 X64,AR0,SZ
+PUSH imm32 \321\154\x68\150 386,SD
PUSHA void \322\1\x60 186,NOLONG
PUSHAD void \321\1\x60 386,NOLONG
PUSHAW void \320\1\x60 186,NOLONG
First of all -- thanks for report. Actually we know about this behavior.
It was done on purpose. In 64bit mode the value being placed on stack is sign extended up to stack size, ie in case of 64bit the 32bit value will be sign extended to 64bit and saved on stack.
But to avoid future confusion and divergence with Intel docs we might apply this patch I guess.
Peter?
I've pushed fix into NASM git repo. In a bit different form since we want to allow "PUSH qword imm" still in a sake of consistency with other pushes semantics.
Note that there is no change on binary level of code being generated by NASM, this only changes semantics (expands it) of asm valid terms.
Thanks again for poking us.