My section of Engineering 100 is Microprocessors and Toys, and having started with combinational logic, we progressed to finite state machines, then instruction set architectures, and finally to Assembly. We implemented simple instructions in Verilog, and we are now finally programming on that processor in Assembly. It’s oddly gratifying, although I have many gripes about Assembly. We are using E100: a heavily simplified instruction set without programmer-accessible registers, but even so these difficulties seem basic enough to be widely applicable. So far, the bugs we’ve run into have not been problems with overall logic but with return and jump addresses. An incorrect return address can often restart the program: memory by default holds a value of zero, which is also the address of the start of the program. This makes for an especially baffling form of infinite loop. Using the incorrect destination label for an unconditional branch leads to chunks of code mysteriously remaining unexecuted. I hope we figure out how to do this better, as currently it is often difficult to tell even what the values of variables are because on the emulator they are just one of many hexadecimal values out of several pages of them. Without the emulator it would be even more difficult. I’d rather stare at a page of numbers than have to add wait-for-key loops and hex digit outputs for each breakpoint and value I was interested in.