cmsc430 / cmsc430.github.io

CMSC 430 Design and Implementation of Programming Languages
https://cmsc430.github.io/
45 stars 33 forks source link

Bit-widths in (some?) operations must be compared #169

Open pdarragh opened 8 months ago

pdarragh commented 8 months ago

A student attempted to compile this code:

;; 2^32 - 16
(seq
  (Mov 'rdx 4294967280)
  (And 'eax 'rdx))

and they got this error:

assembly error: make sure to use `prog` to construct an assembly program
if you did and still get this error; please share with course staff.

/var/tmp/nasm17077944821707794482656.s:8: error: invalid combination of opcode and operands

Apparently, the specification of and cares about the order of the operands: if the left operand is only 32 bits wide (e.g., eax), then the second operand can only be 32 bits wide. However, if the first operand is 64 bits wide (e.g., rax), then the second operand can be of any lesser width (e.g., eax) and that second operand will be sign-extended.

So we'll want to update the checks in the a86 instructions to look for this, and then update the course notes accordingly. I assume and is not the only instruction featuring this behavior, so we'll have to look through the others to see what else ought to be changed.

dvanhorn commented 8 months ago

Hmmm. The only reason we have eax is to support our encoding of strings where we pack two characters per 64-bit word. One option is to drop eax. We could keep the string encoding by reading a 64-bit word and then zeroing out the lower or upper half after the read. Without eax, we wouldn't have to worry about register size agreement.

dvanhorn commented 8 months ago

We also have the cl register, but I don't think that's used.

dvanhorn commented 8 months ago

We could also simplify the encoding of strings to just use a word per character and leave the packed representation as an exercise. In any case, I lean toward the simpler machine model where everything is 64-bits.