Exercise 01 Final Styled Assignment Notes
Exercise 01 Final Styled Assignment Notes
Assignment Notes
Exercise 01 – Page 23
Okay, here are the answers to your NASM/AFD assembly exercises, covering the basics
of computer architecture and the 8088 processor.
How the processor uses the address bus, the data bus, and the control bus to
communicate with the system memory?
Memory Read: The processor places the memory address it wants to read data from
onto the address bus. It then asserts the appropriate signals on the control bus (e.g., a read
signal). The memory unit decodes the address, retrieves the data from that location, and
places it onto the data bus. The processor then reads the data from the data bus.
Memory Write: The processor places the memory address it wants to write data to onto
the address bus. It places the data to be written onto the data bus. It then asserts the
appropriate signals on the control bus (e.g., a write signal and potentially a memory enable
signal). The memory unit decodes the address and stores the data from the data bus at that
location.
In essence, the address bus specifies where, the data bus carries what, and the control bus
specifies how (read/write, when, etc.).
Which of the following are unidirectional and which are bidirectional?
a. Address Bus: Unidirectional (from the CPU to memory or I/O devices – the CPU sends
the address).
b. Data Bus: Bidirectional (data flows both ways between the CPU and memory/I/O –
the CPU can read data or write data).
c. Control Bus: Bidirectional (control signals go from the CPU to devices, like read/write
commands, and status signals or interrupts can go from devices to the CPU).
What are registers and what are the specific features of the accumulator,
index registers, program counter, and program status word?
Registers: Registers are small, high-speed storage locations located within the CPU
itself. They are used to temporarily hold data, memory addresses, and control information
that the CPU is currently working with. Accessing data in registers is much faster than
accessing data in main memory.
Accumulator (e.g., AX on 8088): A general-purpose register, but often used implicitly by
many arithmetic and logic instructions. It's frequently the source and/or destination for
operations. On the 8088, AX is 16-bit, and its 8-bit halves (AL and AH) can be accessed
separately.
Index Registers (e.g., SI, DI on 8088): These registers are primarily used to hold offsets
for memory addressing, especially in operations involving sequences of data like strings or
arrays. SI (Source Index) is often used for source addresses, and DI (Destination Index) for
destination addresses.
Program Counter (e.g., IP on 8088): This register holds the offset of the next instruction
to be fetched and executed within the current code segment. It is automatically incremented
after each instruction fetch and can be modified by control flow instructions like jumps,
calls, and returns.
Program Status Word (PSW) / Flags Register (e.g., FLAGS on 8088): This register
contains a collection of individual bits called "flags". These flags reflect the outcome of
recent arithmetic or logic operations (e.g., whether the result was zero, negative, caused a
carry/overflow) and control the CPU's operation (e.g., enabling/disabling interrupts).
Conditional branching instructions typically test the state of one or more flags.
What is the size of the accumulator of a 64bit processor?
On a 64-bit processor (like modern x86-64 CPUs), the primary accumulator
register (RAX) is 64 bits wide. It also includes 32-bit (EAX), 16-bit (AX), and 8-
bit (AL, AH) sub-registers for backward compatibility and smaller operations.
Data Transfer Instructions: Move data between registers, memory, and I/O ports (e.g.,
MOV, PUSH, POP, IN, OUT).
Arithmetic Instructions: Perform arithmetic operations (e.g., ADD, SUB, MUL, DIV, INC,
DEC).
Logic Instructions: Perform bitwise logical operations (e.g., AND, OR, XOR, NOT, TEST).
Control Flow Instructions: Alter the sequence of instruction execution (e.g., JMP, CALL,
RET, conditional jumps like JZ, JNE).
String Instructions: Operate on blocks of memory (strings) efficiently (e.g., MOVS, CMPS,
SCAS).
Bit Manipulation Instructions: Shift, rotate, or test individual bits (e.g., SHL, SHR, ROL,
ROR, BT).
Processor Control Instructions: Modify processor state or flags (e.g., STC, CLC, NOP,
HLT).
A combination of 8bits is called a byte. What is the name for 4bits and for
16bits?
4 bits: A nibble
16 bits: A word (specifically in the context of the 8088 and x86 architecture, where the
native data size is often considered a word).
What is the maximum memory 8088 can access?
The 8088 microprocessor has a 20-bit address bus, which allows it to access
up to 2^20 bytes of memory. This is equal to 1,048,576 bytes or 1 MB.
List down the 14 registers of the 8088 architecture and briefly describe their
uses.
The 8088 architecture includes 14 user-accessible registers:
Status Flags:
CF (Carry Flag)
PF (Parity Flag)
AF (Auxiliary Carry Flag)
ZF (Zero Flag)
SF (Sign Flag)
OF (Overflow Flag)
Control Flags:
TF (Trap Flag)
IF (Interrupt Enable Flag)
DF (Direction Flag)
Here are the descriptions for the requested flags:
Zero Flag (ZF): Set (1) if the result of an operation is zero. Cleared (0) otherwise.
Carry Flag (CF): Set (1) if there is an unsigned overflow out of the most significant bit
during an arithmetic operation (e.g., carry out of bit 15 for a 16-bit operation). It's also used
as a borrow flag in subtractions. Used in multi-precision arithmetic.
Sign Flag (SF): Set (1) if the most significant bit of the result is 1. In two's complement
representation, this indicates a negative result. Cleared (0) if the MSB is 0 (indicating a non-
negative result). SF is a copy of the MSB of the result.
Overflow Flag (OF): Set (1) if there is a signed overflow. This happens when the result of
a signed arithmetic operation is too large or too small to be represented within the
destination's bit width using two's complement (e.g., adding two positive numbers results
in a negative number, or adding two negative numbers results in a positive number).
Give the value of the zero flag, the carry flag, the sign flag, and the overflow
flag after each of the following instructions if AX is initialized with 0x1254 and
BX is initialized with 0x0FFF.
Initial: AX = 0x1254 (0001 0010 0101 0100), BX = 0x0FFF (0000 1111 1111
1111)
Endianness refers to the order in which bytes of a multi-byte data type (like a word or
double word) are stored in memory.
Big Endian: The most significant byte (MSB) of the data is stored at the lowest memory
address, and the least significant byte (LSB) is stored at the highest memory address. (Think
of writing a number like 123 - you write the most significant digit first).
Little Endian: The least significant byte (LSB) of the data is stored at the lowest memory
address, and the most significant byte (MSB) is stored at the highest memory address.
(Think of writing a number like 123 from right to left - you write the least significant digit
first).
The Intel 8088 microprocessor and all subsequent Intel x86 processors use the little endian
format.
For each of the following words identify the byte that is stored at lower memory
address and the byte that is stored at higher memory address in a little endian computer.
In little endian, the byte at the lower address is the LSB, and the byte at the higher address
is the MSB.
a. 1234 (Hex): Word is 0x1234. LSB = 0x34, MSB = 0x12.
Lower address: 34
Higher address: 12
b. ABFC (Hex): Word is 0xABFC. LSB = 0xFC, MSB = 0xAB.
Lower address: FC
Higher address: AB
c. B100 (Hex): Word is 0xB100. LSB = 0x00, MSB = 0xB1.
Lower address: 00
Higher address: B1
d. B800 (Hex): Word is 0xB800. LSB = 0x00, MSB = 0xB8.
Lower address: 00
Higher address: B8
What are the contents of memory locations 200, 201, 202, and 203 if the word
1234 is stored at offset 200 and the word 5678 is stored at offset 202?
Assuming little endian (as used by 8088):
Why a segment start cannot start from the physical address 55555.
A segment must always start at a physical memory address that is a multiple
of 16. Such an address is called a paragraph boundary. Physical addresses
generated by the 8088 (and subsequent x86 processors using this
segmentation scheme) are calculated as Physical Address = (Segment Register
Value * 16) + Offset. When the offset is 0, the physical address is Segment
Register Value * 16. Since any integer multiplied by 16 will result in a multiple
of 16, a segment must start at a multiple of 16.
The physical address 55555 (decimal) is not a multiple of 16 (55555 / 16 =
3472 with a remainder of 3). In hexadecimal, 55555 is 0xD903. Addresses that
are multiples of 16 always end in a hexadecimal digit of 0 (e.g., 10h, 20h, 100h,
12340h). Since 0xD903 does not end in 0, it is not a paragraph boundary, and
therefore cannot be the starting address of a segment.
a. 1DDD:0436
(0x1DDD * 0x10) + 0x0436 = 0x1DDD0 + 0x0436 = 0x1E206
b. 1234:7920
(0x1234 * 0x10) + 0x7920 = 0x12340 + 0x7920 = 0x19C60
c. 74F0:2123
(0x74F0 * 0x10) + 0x2123 = 0x74F00 + 0x2123 = 0x77023
d. 0000:6727
(0x0000 * 0x10) + 0x6727 = 0x00000 + 0x6727 = 0x06727
e. FFFF:4336
(0xFFFF * 0x10) + 0x4336 = 0xFFFF0 + 0x4336 = 0x104326.
Note: On the 8088, the address bus is only 20 bits, so the result is truncated to 20 bits.
The resulting physical address is 0x04326.
f. 1080:0100
(0x1080 * 0x10) + 0x0100 = 0x10800 + 0x0100 = 0x10900
g. AB01:FFFF
(0xAB01 * 0x10) + 0xFFFF = 0xAB010 + 0xFFFF = 0xB500F
What are the first and the last physical memory addresses accessible using the
following segment values?
A segment register defines a 64KB (0x10000 bytes) region of memory.
a. Copy BL into CL
mov cl, bl
b. Copy DX into AX
mov ax, dx
c. Store 0x12 into AL
mov al, 0x12
d. Store 0x1234 into AX
mov ax, 0x1234
e. Store 0xFFFF into AX
mov ax, 0xFFFF
Write a program in assembly language that calculates the square of six by
adding six to the accumulator six times.
This program uses the ADD instruction inside a loop controlled by the LOOP
instruction (which requires the count in CX). This is a simple COM file
structure suitable for tools like AFD.
org 0x100 ; Indicate that the program starts at offset 0x100 (for COM files)
start:
; Initialize AL (accumulator) to 0. This will hold the sum.
mov al, 0
add_loop:
; Add 6 to the current value in AL
add al, 6
; After the loop finishes, AL will contain the sum (0 + 6*6 = 36)
; End of program