HNHacker News
TopNewBestAskShowJobs

_vm74

1 karma · joined November 21, 2022

submissionscomments
_vm74··on Introduction to x64 Assembly (2011) [pdf]
If you're into any electronics tinkering at all, a good way to get up to speed with assembly is to take a look at some microcontrollers, such as PIC and make some simple hardware projects happen. There are tons of project blueprints out there along with code. The beauty of it is that you can account for pretty much every peripheral on the device with your eyeball. There are many versions of microcontrollers, but a grandfather one with RISC assembly is the venerable PIC16F84A. It has 1 kb of program memory, 68 bytes of ram, and 64 bytes of 'eeprom' ram. That last part is like hard drive storage you can store settings in, or temperatures, or whatever.

The great thing is that you can download the IDE for the chips, write a program, and simulate its running for free. The debugger will light up pins as needed and let you simulate input. But, back to the understanding part: today's CPUs are very complicated and have tons of parts. The microcontroller is a very simplified version of it, and even so it's complicated.

Imagine a microchip in your hand with 18 pins on it. 2 of the pins are power supply (+5 v and ground), another 2 are supposed to be attached to a crystal oscillator (for its CPU clock), 1 pin is a reset button of sorts (or rather a permission to run connection). That leaves you with 13 pins to understand.

The remaining 13 pins are separated into ports "A" and "B", both of which you can address in software and either read or turn individually on or off. Port A has 5 pins and port B has 8 pins you can use for anything you like.

5 of the pins from port B can be optionally used as interrupts, just like on your desktop/laptop. Signal going into them, when configured for it, will interrupt your program and let you respond. Like an alarm sensor going off, needing immediate attention.

If I recall correctly, any of the pins can be configured to do either reading or writing, though I can't remember if you can change that mid-program or just configure startup time.

Normally, you fire up the MicroChip (company name) IDE, write a program, put a blank microcontroller in a simple "programmer" device (USB, or old school serial) and tell it to copy the program over. These microcontrollers are reprogrammable, so you have plenty of room for trial and error.

Anyhow, in your very beginning of the assembly program, you tell the IDE what device you're about to program and how to configure it for the 'burn' and running:

  processor 16f84a
  #include <p16f84a.inc>
  __config _HS_OSC & _WDT_OFF & _PWRTE_ON
So far this is not programming yet. This last config line is telling the machine a few things, but only a few. Like "hey I have a crystal connected to it" or "I don't have a crystal, use some internal resistors to simulate a less accurate clock so it can run the program" or "turn code protection on -- meaning microcontroller is not allowed to be overwritten" or "I don't need a babysitter watchdog in case my code freezes because I wrote good code and it won't freeze and the hardware is good too and won't cause a freeze either". Anyhow, here's some actual code.

  movlw    B'00000011'
  tris     PORTA
  movlw    B'00000000'
  tris     PORTB
  clrf     PORTB
This part defines how I want the pins on two ports to behave. B'' notation means binary, so you can clearly see pins in code. I load an instruction byte that defines pins (written in binary) to a working register (W), then copy the working register to PORT A/B with the TRIS command and that sets the port operation. Anyhow, in this code there I set two pins on port A as inputs for little contact switches. Specifically, pins 18 and 17 on the chip are buttons. Rest, including port B are all outputs, connected to LEDs.

After this point you have your chip up and running. If you had 8 LEDs connected to individual pins on port B (via appropriate resistor of course), you can turn every other one on with this simple program:

  main:
    movlw    B'10101010'
    movwf    PORTB
    goto     main
The 1 corresponds to an LED being on, 0 to off. If you wrote B'11111111' they would all be on (actually maybe they'd be off, I can't remember if a 1 or a 0 is a voltage low or voltage high, but you get the picture!)

Here's what a programmer device looks like that lets you transfer a program from a PC to the microchip: http://pp19dd.com/_old/geocities/geocities.com/krusko.geo/jd... - you put the chip in the socket, plug it into a serial port, and hit a key on the keyboard.

Here's the same microchip controlling a bunch of LEDs for a clock display: http://pp19dd.com/_old/geocities/geocities.com/krusko.geo/7s...

Here's how great this stuff is. The microchip only has 8 outputs for port B, but in it I'm able to control 4 digits, each requiring 8 leds. In other words, I'm controlling 32 LEDs with only 8 pins. Way this happens is that I'm multiplexing at high speed through the 4 displays, and each one is only turned on for a fraction of a second.

Anyhow, there are tons of resources on this chip and its version of assembly out on the web, including this repository of hundreds of projects with code and hardware descriptions: http://pic-microcontroller.com/project-list/

The fun stuff in this assembly language is that there are only about 50 instructions total, so writing simple algorithms like "divide this number by 2" or "multiply this number by 3" or "take square root of 14" become fun academic challenges.

If you're interested, take a look at this brief tutorial titled "PIC Assembly Language for the Complete Beginner": http://www.covingtoninnovations.com/noppp/picassem2004.pdf