From: Peter J. <pe...@to...> - 2008-03-20 16:01:07
|
On Thu, 20 Mar 2008 05:21:48 -0700, H. Peter Anvin wrote > Peter Johnson wrote: > > On Wed, 19 Mar 2008, H. Peter Anvin wrote: > >> anonymous coward wrote: > >>>>> 5 0000000A 68FFFFFFFF push 0xffffFFFF ; doesn't fit into sbyte -> dword > >>>> Broken. The sbyte form is functionally identical. > >>> Wrong. > >>> > >>> The user did request FFFF_FFFF, which is 0000_0000_FFFF_FFFF. > >>> Which is different from sign-extending FF to FFFF_FFFF_FFFF_FFFF. > >>> > >> Talking about 32-bit mode here; for 64-bit mode, you're of course correct. > > > > Actually, you can't encode push 0000_0000_FFFF_FFFF in 64-bit mode. Push > > imm32 in 64-bit mode sign-extends the imm32. So 6AFF and 68FFFFFFFF are > > exactly equivalent in 64-bit mode (they both push FFFF_FFFF_FFFF_FFFF). > > > > Well, "push 0FFFFFFFFh" should give a warning in 64-bit mode, since > it will push something other than what the user requested. It could > still be downgraded to a 2-byte sequence (6A FF) since the behaviour > is identical to the equally flawed 5-byte sequence (68 FF FF FF FF). > > However, in 32-bit mode, the two-byte sequence 6A FF will push > FFFFFFFF on the stack, so "push 0FFFFFFFFh" should silently be > compressed to a two-byte sequence. Yes, exactly. Likewise push 0FFFFFFFFFFFFFFFFh in 64-bit mode should be encoded as two bytes, but warn and 2-byte encode in 32-bit mode. Yasm already correctly warns for the push 0FFFFFFFFh case in 64-bit mode, but I've not yet optimized its encoding to 2-byte. I have a patch (for Yasm) for all other optimization cases but this one ready to commit. It's about 10 added lines of code :). -Peter |