Assembly language translates almost directly to machine code. mov
becomes a mov
instruction. call
becomes a call
instruction. The arguments on the same line become the argument fields for those instructions. There's a bit of assistance in computing addresses, but not a lot beyond that.
The operating system can be treated much like a subroutine library. The "magic numbers" you're asking about are operating system entry points; the call
instruction, like a function call in higher level languages, invokes them; they run until they return
, at which point your program picks up where it left off. Your OS's user manual will tell you which entry point to invoke to do what, how to set up any arguments required (such as putting the address of the string to be printed in the si register before calling os_print_string
, though some may involve pushing values onto the stack rather than putting them in registers), and how to read their returned results if any (again, which registers will have the result or what to pop off the stack).
As far as question (b) goes -- That's all stuff the OS and its device drivers, or a function library linked with your assembly code, will normally handle for you. If you really need to know it (eg because you're writing an OS or device drivers), you'll need to study the documentation for your specific hardware to understand how to communicate with it... but what you'll wind up doing is writing a library of functions which do the necessary work, and packaging it so main programs just invoke those functions. In other words, for most programs I/O is much like working in a higher-level language; the runtime library does all the work and all you need to know is how to use it. (Sane assembler code is critically dependent upon writing good functions so you don't spend time endlessly reinventing wheels!)
1)
An Instruction Set Architecture defines the interface that is used to program a processor. Note that this does not define the implementation. When a CPU designer goes about designing the processor, they may implement this ISA in various different ways. In fact, the various Intel processors have each implemented the x86 ISA in many different ways over the years.
Computer architecture is generally delineated around an ISA. Computer microarchitecture is very specific to a particular processor. For example, a Pentium vs. a Pentium Pro implement for the most part the exact same instruction set, i.e. the x86 ISA. But their microarchitectures were drastically different. (The Pro was out of order for example).
One of the methods often used to get pipelines to be very fast is to reduce the more complex instructions to microinstructions. These are used by the "back-end" of the processor, which is the part that has one or more execution units.
Therefore, the point of the two types of instructions ISA instruction vs. microinstruction has to do with whether you are discussing the ISA, i.e. the interface, or the microarchitecture, i.e. the implementation.
2)
As far as your second question, Tanenbaum was almost certainly talking about ISA level instructions because his books are about computer architecture. Microarchitecture is much more hardware designer centric. See John Stokes, "Inside the Machine" if you are interested in microarchitecture.
3)
For most real processors, fetch-decode-execute is entirely too simplistic to describe what really goes on inside. However, from an ISA point of view, it defines a good abstraction to the steps an instruction takes.
The instruction fetch is done by dedicated hardware, so it is different from the load instruction data fetch. Usually there are actually two bus masters, instruction and data. These buses often have their own caches. In some cases, i.e. harvard architectures, the data and instruction memory maps are entirely separate.
4)
RISC vs. CISC is entirely regarding the ISA, i.e. the interface. However, the RISC mindset of using a reduced instruction set is very much to simplify the microarchitecture. The effect is that the microarchitectural instructions are generally exactly the same as the ISA instructions in RISC processors.
Best Answer
It depends.
Some (CISC) CPUs have byte-wise loads that can address individual bytes so the byte of interest is the low-order 8-bits on the bus; the rest of the bits are masked off.
Many RISC CPUs will do word-load, barrel shift, while others will do word-load, bit shift and in the middle, are ones that do word-load, byte shift.
Some CPUs will do consecutive word-loads when a two-byte value spans a 32-bit boundary, shifting and masking the words together.
CPU families may do different implementations depending on the particular processor model. That explains why there is no description of the implementation; it's a decision only the vendor cares about.
As for performance, you will just have to test it on the particular CPU and memory configurations you care about.