While looking through Intel’s Instruction Set Reference, I noticed that the the opcodes for pushing a 16-, 32-, and 64-bit register are the same (50+rw, 50+rd, and 50+rd, respectively).
How does the processor know which register it needs to push to the stack if all of the opcodes are the same? If it depends on the current operating mode, then if you push ax in protected mode, are the upper 16 bits of eax pushed to the stack, too?
Your assumptions is slightly off (I don’t blame you, intels manuals can very very cryptic sometimes), yes, they may have the same base opcode, but sizes differing from 32 require a size override prefix, eg:
Here we can see the 16 bix size override prefix,
0x66, is used whenPUSH‘ingAX.this is one reason you can’t push byte registers, cause there is no size override prefix available to do this.