MIPS is a really good way to learn all of this stuff, plus there are lots of resources. Usually all of the registers will be 32 bit wide on a 32 bit processor, once a 16 bit value is moved into a register it's usually padded with zeros. I'm speaking from a broad MIPS perspective here
Consider the following,
Code:
int x = 5, y = 10, r = 0;
r = x + y;
Might be:
Code:
.data
x:
.word 5
y:
.word 10
r:
.word 0
.text
main:
lw $t0, x # load word...
lw $t1, y
add $t0, $t0, $t1
sw $t0, r # store word...
But how would "addi $t0, $0, 156" (add immediate) fit into 1 word you ask? (be it 32 bits or whatever). Thus any effort you went to to have a 'optimum' data type would go to waste (as shifting/padding must occur anyway). Of course 156 would have to be shifted to 32 bits to fit in a register / go in memory. Since,
Code:
addi (6 bits) $t0 (5 bits -- 32 registers) $0 (5 bits -- again, 32 registers) 156 (only have 16 bits to represent immediate value)
> Would it be more efficient to have a program that packs say 4 chars into a int, when it comes to loading from memory?
Perhaps, but packing and unpacking is most likely going to be slower than going to memory 4 times... Not to mention the assembler will often pack itself (if memory is byte addressable).
I might be wrong... but hey, at least I'm adding more fuel to the fire. I'd suggest playing around with MIPS (ie a simulator MARS is good). Does wonders for learning.