Some points of Assembly Language 2024
This is a site for some points about the course Assembly Language, Spring 2024, taught by Леонов Александр Георгиевич, on the online course platform mirera.ru.
16-bit computing
True Form, Ones’ Complement and Two’s Complement
True Form
Sign-magnitude is the most intuitive representation method. In sign-magnitude, the most significant bit (often called the sign bit) is used to represent the sign of the number, where 0 denotes a positive value and 1 denotes a negative value. The remaining bits represent the magnitude of the number.
For example, if we represent a decimal number using 8-bit binary:
-
+9in sign-magnitude is00001001(the first bit is the sign bit,0for positive, followed by the 7-bit binary representation of the number 9). -
-9in sign-magnitude is10001001(the first bit is the sign bit,1for negative, the next 7 bits still represent the number 9).
The range of integers that can be represented:
- The range for positive numbers:
00000001to01111111, which corresponds to decimal1to127. - The range for negative numbers:
10000001to11111111, which corresponds to decimal-1to-127. - Positive zero:
00000000, which corresponds to decimal0. - Negative zero:
10000000, which is considered as-0in sign-magnitude representation, but in reality,-0is equivalent to+0in value.
Thus, using sign-magnitude, an 8-bit register can represent integers in the range of -127 to +127, plus a 0.
Ones’ Complement
Ones’ complement is used for representing negative numbers. For positive numbers, the ones’ complement is the same as the sign-magnitude; for negative numbers, the ones’ complement is obtained by inverting all the bits of the magnitude part of the number.
Continuing with the same examples:
-
+9in ones’ complement remains the same as its sign-magnitude, which is00001001. -
-9in ones’ complement is11110110(the sign bit remains1, while the rest of the bits are inverted).
The range of integers that can be represented:
- The range for positive numbers: Same as sign-magnitude, from
00000001to01111111, decimal1to127. - The range for negative numbers:
11111110to10000000, decimal-1to-127(note that negative numbers are the inversion of their magnitude). - Positive zero:
00000000, decimal0. - Negative zero:
11111111, which is the representation of-0in ones’ complement.
The integer range for ones’ complement representation is also -127 to +127, but there are two representations for zero.
Two’s Complement
Two’s complement is also used to represent negative numbers and is the standard in modern computer systems. For positive numbers, the two’s complement is the same as the sign-magnitude; for negative numbers, the two’s complement is found by adding one to the ones’ complement of the number’s magnitude.
Continuing with the same examples:
-
+9in two’s complement is the same as its sign-magnitude,00001001. -
-9in two’s complement is the ones’ complement11110110plus one, resulting in11110111.
The range of integers that can be represented:
- The range for positive numbers: Same as sign-magnitude and ones’ complement, from
00000001to01111111, decimal1to127. - The range for negative numbers:
11111111to10000000, decimal-1to-128. Note that in two’s complement,10000000represents-128. - Zero:
00000000, in two’s complement, there is only one representation of zero, decimal0.
Common Arithmetic Instructions
| Command | Action | Example | Flag Z | Flag C |
|---|---|---|---|---|
| DEC d | d = d-1 | DEC AX | ✓ | - |
| INC d | d = d+1 | INC [BX] | ✓ | - |
| ADD d,s | d = d+s | ADD AX, 20 | ✓ | ✓ |
| SUB d,s | d = d-s | SUB CX, [1] | ✓ | ✓ |
| MOV d,s | d = s | MOV AX, [100] | - | - |
| ADC d,s | d = d+s+C | ADC [AX], 20 | ✓ | ✓ |
| SBB d,s | d = d-s-C | SBB [02], 1 | ✓ | ✓ |
| CMP d,s | d - s | CMP AX, [1] | ✓ | ✓ |
| POP d | d = [SP–] | POP BX | - | - |
| PUSH d | [++SP] = d | PUSH [102] | - | - |
| AND d,s | d = d & s | AND AX, [1] | ✓ | 0 |
| OR d,s | d = d | s | OR [BX], [AX] | ✓ | 0 |
| NEG d | d = -d | NEG [AX] | ✓ | ✓ |
| RCL d | C -> \(d_0\),d = d*2,\(d_{15}\) -> C | RCL BX | - | ✓ |
| RCR d | C -> \(d_{15}\),d=d/2,\(d_0\)-> C | RCR [2] | - | ✓ |
ADC (Add with Carry)
The ADC instruction stands for “Add with Carry.” It adds the source operand (s), the destination operand (d), and the carry flag (C) together.
Use cases:
- Multi-byte addition:
ADCis used when performing addition operations that exceed the capacity of a single register. For instance, in a 32-bit system, if we need to add two 64-bit numbers, we would need to divide this operation into two parts, each 32 bits, held in two separate registers. First, we add the lower 32 bits, and then useADCto add the upper 32 bits, which automatically includes the carry from the lower addition if there is one. - Extended arithmetic operations: During extended arithmetic operations, such as those found in cryptography or digital signature algorithms, operands can be very large and not fit within a single register.
ADCis useful here to handle each segment of the operand and include carryovers from previous additions.
SBB (Subtract with Borrow)
The SBB instruction stands for “Subtract with Borrow.” It subtracts the source operand (s) from the destination operand (d) and then also subtracts the carry flag (C), which in the context of subtraction is treated as a borrow.
Use cases:
- Multi-byte subtraction: Similar to
ADC,SBBis used for subtraction that involves numbers larger than what a single register can hold. After subtracting the lower part of the operands,SBBhelps to subtract the higher part along with any borrow that resulted from the lower subtraction. - Extended arithmetic operations: For large numerical operations that require precise subtraction over multiple data words,
SBBcan sequentially subtract along with borrows, ensuring that the extended precision is maintained across the entire operation.
Large Number Addition and Large Number Subtraction
To perform large number arithmetic with numbers stored across two registers, you would perform addition or subtraction by handling the carry or borrow flags appropriately.
; Assuming AX:BX contains the first large number (higher part in AX, lower part in BX)
; Assuming CX:DX contains the second large number (higher part in CX, lower part in DX)
; The result will be stored in AX:BX
; First, add the lower parts
ADD BX, DX ; BX = lower part of the first number + lower part of the second number
ADC AX, CX ; AX = higher part of the first number + higher part of the second number + carry
; Assuming AX:BX contains the first large number (higher part in AX, lower part in BX)
; Assuming CX:DX contains the second large number (higher part in CX, lower part in DX)
; The result will be stored in AX:BX
; First, subtract the lower parts
SUB BX, DX ; BX = lower part of the first number - lower part of the second number
SBB AX, CX ; AX = higher part of the first number - higher part of the second number - borrow
Enjoy Reading This Article?
Here are some more articles you might like to read next: