Do you understand how negative values are stored in memory, or represented as hex values?
Run this little program, which prints out the hex values for -1 to -20, as signed bytes, integers, and longs:
v%% = -i: v% = -i: v& = -i
Your output should look like the following:
1 FF FFFF FFFFFFFF
2 FE FFFE FFFFFFFE
3 FD FFFD FFFFFFFD
4 FC FFFC FFFFFFFC
5 FB FFFB FFFFFFFB
6 FA FFFA FFFFFFFA
7 F9 FFF9 FFFFFFF9
8 F8 FFF8 FFFFFFF8
9 F7 FFF7 FFFFFFF7
10 F6 FFF6 FFFFFFF6
11 F5 FFF5 FFFFFFF5
12 F4 FFF4 FFFFFFF4
13 F3 FFF3 FFFFFFF3
14 F2 FFF2 FFFFFFF2
15 F1 FFF1 FFFFFFF1
16 F0 FFF0 FFFFFFF0
17 EF FFEF FFFFFFEF
18 EE FFEE FFFFFFEE
19 ED FFED FFFFFFED
20 EC FFEC FFFFFFEC
Now, as you can see, the value of -1 starts as a full complement of F values. For a byte, it's FF. For an integer, it's FFFF. For a long, it's FFFFFFFF. As your negative value increases, you simply count down from there. FE or FFFE, or FFFFFFFE.
Not only do you need to know your variable value, but you also have to know the variable type, to know what the value is.
So pushing 81 into a single byte gives you the correct value of -0x7F, for that byte.
Now, for the x86 disassembler, you need to remember that your full x86 register is in 32-bit bytes -- EAX.
EAX is the full 32-bit value
AX is the lower 16-bits
AL is the lower 8 bits
AH is the bits 8 through 15 (zero-based)
So 81 as a byte is going to be the same as EAX FFFFFF81.
You pushed 81 into the lowest 8 bits of your 32-bit register, but the disassembler is reporting the value of the whole 32-bit EAX register for you.
And that's the great and mysterious issue you're seeing with your disassembly that has you running around in circles wondering what's going on. It's just basically different ways of representing the same value...
81 as a signed byte = FF81 as a signed integer = FFFFFF81 as a signed long.
That's all there is to it!