All Task of Assembly Language 2024
This is a site for the record of all test answers for the course Assembly Language, Spring 2024, taught by Леонов Александр Георгиевич, on the online course platform mirera.ru.
You can see some of the points about the classroom in “Some points about Assembly Language 2024”.
Lecture 01
0 (Example)
MOV AX,0 ; Move 0 to register AX, i.e., assign the value
2000
Write a program that puts 2000 in the AX register.
MOV AX, 2000
Data
Write a program that puts data from BX in the AX register.
MOV AX, BX
Sum (Example)
Run the program that puts the sum of data from BX and CX into the AX register.
MOV AX,BX
ADD AX,CX
Subtract
Write a program that places the result of subtracting data CX from BX into register AX.
SUB BX, CX
MOV AX, BX
Calculate
Write a program that places the result of operation into register AX.
MOV AX, 0
MOV BX, FF00
MOV CX, F
MOV DX, F1
AND CX, DX
OR CX, 80
MOV AX, BX
OR AX, C0
ADD AX, CX
NEG AX
Swap
Write a program that swaps two numbers in registers BX and CX.
MOV AX, BX
MOV BX, CX
MOV CX, AX
Swap Return
Write a program that swaps two numbers in registers BX and CX (Not use Push/Pop or other registers)!
ADD BX, CX
SUB CX, BX
NEG CX
SUB BX, CX
NOT
Bitwise Unary NOT (~) performs complementation or negation operation; inverts all the bits of the number, i.e. 0→1 and 1→0.
-
Truth table:
A ~ A 0 1 1 0
Write a program that places the result of operation NOT into register AX. (Not use Push/Pop or other registers)!
NEG AX
DEC AX
Remember!
Write a program that stores two numbers in registers BX and CX between operations.
PUSH BX
PUSH CX
MOV DX,0
MOV CX,0
MOV BX,0
MOV AX,0
POP CX
POP BX
XOR
Exclusive or or exclusive disjunction is a logical operation that is true if and only if its arguments differ (one is 1, the other is 0). Exclusive disjunction is often used for bitwise operations. Examples:
- 1 XOR 1 = 0
- 1 XOR 0 = 1
- 0 XOR 1 = 1
- 0 XOR 0 = 0
Write a program that places the result of operation AX XOR BX into register AX. (Not use Push/Pop or all other registers, you can use only one extra register - CX)!
MOV CX, AX
OR AX, BX
AND BX, CX
NEG BX
DEC BX
AND AX, BX
Left Shift (Example)
Run the program that multiply by 2 a number in the AX register.
Do Not forget CLC before any RCL!
CLC
RCL AX
END
Right Shift
Write a program that divides by 2 the number in register CX and puts the result in register AX.
Do Not forget CLC before any RCR!
CLC
RCR CX
MOV AX, CX
MultiShift
Write a program that puts the value of AX multiplied by 4 into register BX and the value of AX divided by 4 into register CX.
Use the shift operations RCL and RCR.
Do Not forget CLC before any RCL and RCR!
MOV BX, AX
MOV CX, AX
CLC
RCL BX
CLC
RCL BX
CLC
RCR CX
CLC
RCR CX
Sum
Write a program that puts into register AX the sum of two 8-bit numbers stored in 16-bit register BX.
Example: BX = \(032E_{16}\), result AX = \(03_{16} + 2E_{16}\) = \(31_{16}\).
If BX=0, then AX=0.
Use the shift operations RCL or RCR.
Do Not forget CLC before any RCL and RCR!
MOV AX, BX
AND AX, 00FF
MOV CX, BX
CLC
RCR CX
CLC
RCR CX
CLC
RCR CX
CLC
RCR CX
CLC
RCR CX
CLC
RCR CX
CLC
RCR CX
CLC
RCR CX
ADD AX, CX
END
Lecture 02
Zero Comparison (Example)
Run a program that compares BX and CX and sets AX=1 when BX = CX
CMP BX,CX
JNZ ?1
MOV AX,1
?1:
Comparing two numbers
Write a program that puts 1 in register AX if BX \(\ge\) CX and 0 otherwise.
CMP BX, CX
JC ?01
MOV AX, 1
JMP ?02
?01:
MOV AX, 0
?02:
Absolute value
Write a program to put the absolute value of the difference between the numbers in BX and CX into register AX.
CMP BX, CX
JNC ?01
SUB CX, BX
MOV AX, CX
JMP ?02
?01:
SUB BX, CX
MOV AX, BX
?02:
Minimum
Write a program that puts the minimum number of numbers from BX and CX into AX.
CMP BX, CX
JC ?01
MOV AX, CX
JMP ?02
?01:
MOV AX, BX
?02:
Divisible by 3
Write a program that puts 1 in register AX if BX is evenly divisible by 3, and 0 otherwise.
MOV AX, BX
MOV CX, 3
JZ ?03
?01:
SUB AX, 0
JZ ?03
CMP AX, CX
JC ?02
JZ ?03
SUB AX, CX
JMP ?01
?02:
MOV AX, 0
JMP ?04
?03:
MOV AX, 1
?04:
Divisible by 2
Write a program that puts 1 in register AX if BX is evenly divisible by 2, and 0 otherwise.
(Do not use all other registers, except AX and BX or any Jump command)!
MOV AX, 1
AND BX, 1
SUB AX, BX
Bit number
Bits in a 16-bit register are numbered from 1 (least significant bit) to 16. Write a program that finds the least significant non-zero bit number of register BX and puts the answer into register AX.
If BX=0, then AX=0.
Use the RCR shift operation.
Example: BX=\(0006_{16}\) (0000 0000 0000 01102), AX=2.
MOV CX, 0
MOV AX, BX
OR AX, AX
JZ ?01
MOV CX, 1
?02:
RCR BX
JC ?03
INC CX
JMP ?02
?03:
MOV AX, CX
JMP ?04
?01:
MOV AX, 0
?04:
Number of different numbers
Write a program that puts in register AX the number of different numbers in BX, CX, DX.
Example:
- DX = 0
- BX = 1
- CX = 2
- Answer AX = 3
MOV AX, 3
CMP BX, CX
JNZ ?01
DEC AX
?01:
CMP BX, DX
JNZ ?02
DEC AX
?02:
CMP CX, DX
JNZ ?03
DEC AX
?03:
CMP AX, 1
JNC ?04
MOV AX, 1
?04:
Number of maximum
Write a program that counts the maximums in the sequence BX, CX, DX and places the result in the AX register. For example, in the sequence of numbers 1,2,3 - the maximum is unique and equals 3 (BX=1, CX=2, DX=3 ⇒ AX=1) In the sequence of numbers 3,1,3 - the maximum is 3 and there are 2 such numbers in the sequence (BX=3, CX=1, DX=3 ⇒ AX=2).
MOV AX, 1
?00:
CMP BX, CX
JC ?01
JZ ?02
?03:
CMP BX, DX
JC ?04
JZ ?05
JMP ?06
?01:
MOV BX, CX
MOV AX, 1
JMP ?03
?02:
INC AX
JMP ?03
?04:
MOV BX, DX
MOV AX, 1
JMP ?06
?05:
INC AX
JMP ?06
?06:
Sides of a triangle
Can non-negative integers in BX, CX, DX be sides of a triangle?
The result will be AX=1 if YES and AX=0 if NOT.
ADD BX, CX
MOV AX, BX
SUB BX, CX
SUB AX, DX
JZ ?00
JC ?00
MOV AX, 1
ADD BX, DX
MOV AX, BX
SUB BX, DX
SUB AX, CX
JZ ?00
JC ?00
MOV AX, 1
ADD CX, DX
MOV AX, CX
SUB CX, DX
SUB AX, BX
JZ ?00
JC ?00
MOV AX, 1
JMP ?03
?00:
MOV AX, 0
?03:
Right triangle
Can non-negative integers in BX, CX, DX be sides of a right triangle?
The result will be AX=1 if yes, and AX=0 if not.
Note. A triangle with sides {0,0,0} is not a right triangle.
PUSH DX
PUSH CX
MOV AX, BX
MOV CX, BX
DEC AX
?01:
ADD BX, CX
DEC AX
JZ ?02
JMP ?01
?02:
POP CX
POP DX
PUSH BX
PUSH DX
MOV AX, CX
MOV BX, CX
DEC AX
?03:
ADD CX, BX
DEC AX
JZ ?04
JMP ?03
?04:
POP DX
POP BX
PUSH BX
PUSH CX
MOV AX, DX
MOV BX, DX
DEC AX
?05:
ADD DX, BX
DEC AX
JZ ?06
JMP ?05
?06:
POP CX
POP BX
MOV AX, 0
CMP BX, 0
CMP CX, 0
CMP DX, 0
JZ ?07
ADD BX, CX
CMP BX, DX
JZ ?09
SUB BX, CX
ADD BX, DX
CMP BX, CX
JZ ?09
SUB BX, DX
ADD CX, DX
CMP CX, BX
JZ ?09
SUB CX, DX
JMP ?07
?09:
MOV AX, 1
?07:
Long shift to the left
Run a program that doubles a 32-bit number from the BX AX registers (lower part of AX).
RCL shift operations are used.
CLC
RCL AX
RCL BX
Long shift to the right
Write a program that divides a 32-bit number from the BX AX registers (lower part of AX) by 4.
RCR shift operations are used.
RCR BX
RCR AX
RCR BX
RCR AX
Adding two long
Write a program that adds a 32-bit long number stored in the CX, DX registers with a long number stored in the AX, BX registers.
ADD BX, DX
JC ?00
JMP ?01
?00:
INC AX
?01:
ADD AX, CX
Bus for programmers
Bus tickets for programmers have a hexadecimal number. We call a ticket lucky if the sum of the two left hexadecimal digits is equal to the sum of the two right digits, for example ADE9. Example of an unsuccessful ticket: 7+8≠9+3. How many lucky ticket numbers are found from number BX to number CX, including borders?
; Code to achieve the task goal: to determine whether a number is a lucky vote or not
; Method: Read four 4-bit binary numbers in sequence using 0 and 1 operations, and then use RCR to transfer the data to the real data.
; Then, judge whether the final result is 0 by adding and subtracting to determine whether it is a lucky number of votes.
SUB CX, BX ; Subtract BX from CX, result stored in CX
ADD CX, 2 ; Add 2 to CX, adjusting the loop counter
?00:
DEC CX ; Decrement CX by 1
JZ ?03 ; Jump to label ?03 if CX is zero (end of loop condition)
MOV [1], BX ; Store the value of BX into memory location addressed by 1
AND BX, 0F ; Perform bitwise AND between BX and 0F, isolating the lowest 4 bits
MOV DX, BX ; Move the result of AND operation into DX
MOV BX, [1] ; Restore BX from memory location addressed by 1
AND BX, F0 ; Perform bitwise AND between BX and F0, isolating bits 4-7
CLC ; Clear carry flag to prepare for rotate operation
RCR BX ; Rotate BX right through carry, shifting bits 4-7 to 0-3
RCR BX
RCR BX
RCR BX ; Repeat rotation to complete the shift of bits 4-7 to 0-3
ADD DX, BX ; Add the newly shifted bits in BX to DX
MOV BX, [1] ; Restore BX from memory location addressed by 1
AND BX, F00 ; Perform bitwise AND between BX and F00, isolating bits 8-11
CLC ; Clear carry flag to prepare for rotate operation
RCR BX ; Rotate BX right through carry, shifting bits 8-11 towards lower bit positions
RCR BX
RCR BX
RCR BX
RCR BX
RCR BX
RCR BX
RCR BX
RCR BX ; Repeat rotation to complete the shift of bits 8-11 to 0-3
SUB DX, BX ; Subtract the shifted value in BX from DX
MOV BX, [1] ; Restore BX from memory location addressed by 1
AND BX, F000 ; Perform bitwise AND between BX and F000, isolating bits 12-15
CLC ; Clear carry flag to prepare for rotate operation
RCR BX ; Rotate BX right through carry, shifting bits 12-15 towards lower bit positions
RCR BX
RCR BX
RCR BX
RCR BX
RCR BX
RCR BX
RCR BX
RCR BX
RCR BX
RCR BX
RCR BX
RCR BX ; Repeat rotation to complete the shift of bits 12-15 to 0-3
SUB DX, BX ; Subtract the final shifted value in BX from DX
CMP DX, 0 ; Compare DX with 0
JZ ?01 ; Jump to label ?01 if DX is zero (if comparison equals zero)
MOV BX, [1] ; Restore BX from memory location addressed by 1
INC BX ; Increment BX
JMP ?00 ; Jump back to start of loop at label ?00
?01:
INC AX ; Increment AX
MOV BX, [1] ; Restore BX from memory location addressed by 1
INC BX ; Increment BX
JMP ?00 ; Jump back to start of loop at label ?00
?03: ; Label ?03, marks the end of the loop or a specific condition block
Lecture 03
Contents of an Address
Write a program that puts the contents at address BX into register AX.
MOV AX, [BX]
Contents of 2
Write a program that gets the number plus 200 from the BX register. Place the result in the AX register.
Example: BX=\(100_{16}\) ⇒ AX=\(300_{16}\)
ADD BX, 200
MOV AX, BX
Contents of an Address 3
Write a program that gets the number plus \(200_{16}\) located at address BX. Place the result in the AX register.
ADD [BX], 200
MOV AX, [BX]
Sum of three numbers
Write a program that puts the sum of the three numbers at addresses 0, 1, and 2 into register AX.
ADD AX, [0]
ADD AX, [1]
ADD AX, [2]
Amount by address
Write a program that substitutes into register AX the sum of three numbers located at addresses BX, BX+1, BX+2.
ADD AX, [BX]
INC BX
ADD AX, [BX]
INC BX
ADD AX, [BX]
Array Sum
Write a program that puts into register AX the sum of an array of length CX, starting at address BX.
The sum of an empty array is 0.
?00:
CMP CX, 0
JZ ?01
ADD AX, [BX]
DEC CX
INC BX
JMP ?00
?01:
Equal array
Write a program that puts 1 in register AX if all elements of an array of length CX are equal. The array starts at address BX. The answer is 1 if the array has length 0.
MOV AX , 1
MOV DX , [BX]
CMP CX , 0
JZ ?02
CMP CX , 1
JZ ?02
DEC CX
?00:
CMP CX , 0
JZ ?02
INC BX
DEC CX
CMP DX , [BX]
JNZ ?01
JMP ?00
?01:
MOV AX , 0
?02:
Address of the first minimum number
Write a program that places the address of the first minimum number in an array of length CX into register AX, starting at address BX.
In the case of an empty sequence, the answer is 0.
MOV AX, 0
CMP CX, 0
JZ ?02
MOV AX , BX
MOV DX , [BX]
?00:
CMP DX , [BX]
JC ?01
JZ ?01
MOV DX , [BX]
MOV AX , BX
?01:
INC BX
DEC CX
JZ ?02
JMP ?00
?02:
The number of all connected increasing subsequences
Write a program that count all connected increasing subsequences. Places the result of an array of length CX, starting at address BX nto register AX.
In the case of an empty sequence, the answer is 0.
Example: 1 2 3 2 3 1 ⇒ AX=3.
MOV AX , 0
CMP CX , 0
JZ ?02
MOV AX , 1
MOV DX , [BX]
INC BX
?00:
DEC CX
CMP CX , 0
JZ ?02
CMP DX , [BX]
JZ ?01
JNC ?01
MOV DX , [BX]
INC BX
JMP ?00
?01:
INC AX
MOV DX , [BX]
INC BX
JMP ?00
?02:
Address of the second maximum
The CX register contains a value - the number of elements of the sequence located starting from the address BX.
In the case of an empty sequence, the answer is 0
If there is no second maximum, the answer is 0.
Example: 1 2 3 2 3 1 ⇒ AX=5.
MOV AX , 0
MOV [01F8] , 0 ; A null address is needed for data transit in this task, and a random address is chosen here, but this is not a good method.
MOV DX , [BX]
ADD CX , 2
?00:
DEC CX
CMP CX , 0
JZ ?10
CMP DX , [BX]
JZ ?01
JC ?03
INC BX
JMP ?00
?01:
INC [01F8]
CMP [01F8] , 2
JZ ?02
INC BX
JMP ?00
?02:
MOV AX , BX
JMP ?00
?03:
MOV DX , [BX]
MOV [01F8] , 1
INC BX
JMP ?00
?10:
Number of local maxima of the sequence
Write a program, after the execution of which, the register AX will contain the number of local maxima of the sequence.
The CX register contains a value - the number of elements of the sequence located starting from the address BX.
In the case of an empty sequence, the answer is 0.
An element of a non-empty sequence is called a local maximum if it has no neighbor greater than itself. For example, a sequence of one element has one local maximum. The sequence 4, 4, 2, 3, 0 has three local maxima: the first, second, and penultimate elements.
; In order to prevent the data outside the specified array will affect the data at both ends, the first judgement CX is not 0,
; then it is a separate judgement of whether the data at both ends are satisfied, and then it is a judgement of whether the data in the middle is satisfied,
; the trap is that if the target data of the right side of the data is greater than it, jump out of the body of the program, at this time, BX (which can be taken as a positional pointer) is still parked in the previous one, and we would like to carry out the judgemental force of the next data, so we should update the BX in time.
MOV AX , 0
CMP CX , 0
JZ ?00
MOV DX , [BX]
INC BX
CMP DX , [BX]
JC ?01
INC AX
?01:
DEC BX
ADD BX , CX
DEC BX
MOV DX , [BX]
DEC BX
CMP DX , [BX]
JC ?02
INC AX
?02:
SUB CX , 2
JZ ?00
?04:
MOV DX , [BX]
INC BX
CMP DX , [BX]
JC ?03
SUB BX , 2
CMP DX , [BX]
JC ?05
INC AX
JMP ?05
?03:
SUB BX,2
JMP ?05
?05:
SUB CX , 1
JNZ ?04
?00:
The lengths of the sides form a parallelogram
The array contains the lengths of the sides of the parallelogram as it is traversed clockwise.
Write a program that puts 1 in register AX if the elements of the array (lengths of sides) of size CX, starting at address BX, form a parallelogram, and zero otherwise.
In case of error data (CX≠4) the answer is 0.
MOV AX , 0
CMP CX , 4
JNZ ?00
MOV DX , [BX]
ADD BX , 2
CMP [BX] , DX
JNZ ?00
ADD BX , 1
MOV DX , [BX]
SUB BX , 2
CMP [BX] , DX
JNZ ?00
MOV AX , 1
?00:
Lecture 04
The subsequence
In memory at address 0, there is a value - the number of elements of the sequence located starting from address 1.
Write a program that leaves the AX register the number of occurrences of the subsequence “1, 2, 3, 1”.
In the case of an empty sequence, the answer is 0
Example: 7 1 2 3 1 2 3 1 ⇒ AX=2.
It is not emphasised here that “1, 2, 3, 1, 2, 3” should be judged as 2 subsequences.
MOV AX , 0
MOV BX , 0
CMP [BX] , 4
JC ?00
?01:
MOV CX , [0]
INC CX
CMP BX , CX
JZ ?00
INC BX
CMP [BX] , 1
JZ ?02
JMP ?01
?02:
INC BX
CMP [BX] , 2
JZ ?03
JMP ?01
?03:
INC BX
CMP [BX] , 3
JZ ?04
JMP ?01
?04:
INC BX
CMP [BX] , 1
JZ ?05
JMP ?01
?05:
INC AX
DEC BX ;The last number is 1 and the counter BX has to go backwards by one, in order to check if this 1 might be the beginning of a subsequence.
JMP ?01
?00:
Even-odd
In memory at address 0, there is a value - the number of elements of an array of natural numbers (and zero also), located starting from address 1.
Let’s call a “strange ascent” the case when there are either even or odd numbers nearby, or the number on the left is odd and the number on the right is even.
Write a program that sorts an array in “strange ascending” order.
Example: 4 3 2 1 2 2 1 ⇒ 3 1 1 4 2 2 2
Remark: Do not change order inside the equivalent class. Wrong answer: 3 1 1 2 4 2 2.
The key to this task is to filter out the odd and even numbers without changing the order in which they are each arranged, and then, arrange the odd numbers first and then the even numbers. Note that the RCR approach is used when determining whether the data in memory is odd or even, but you can’t operate directly on that data because it will affect the data in the memory before and after.
CMP [0] , 0
JZ ?00
MOV BX , 0
?02:
CMP BX , [0]
JZ ?03
INC BX
CLC
MOV DX , [BX]
RCR DX
JC ?01
JMP ?02
?01:
PUSH [BX]
JMP ?02
?03:
MOV BX , 0
?04:
CMP BX , [0]
JZ ?06
INC BX
CLC
MOV DX , [BX]
RCR DX
JNC ?05
JMP ?04
?05:
PUSH [BX]
JMP ?04
?06:
MOV BX , [0]
?07:
CMP BX , 0
JZ ?00
POP [BX]
DEC BX
JMP ?07
?00:
Adding two long numbers
Write a program that implements the operation of adding two very long numbers.
Integers in the range 0 to \(2^{1024}-1\) are represented as 𝑁 ≤ 64 consecutive words of memory each.
Register AX is the address of the first least significant word of the first number, BX=𝑁 is the length of the number.
The numbers are in order, so the address of the first digit of the second number is AX+BX. The result must be in the first number.
This task pays special attention to the progression, whether there are two numbers produced by adding them together or by the progression of the previous sum.
MOV DX , 0
MOV CX , BX
?00:
CMP AX , CX
JZ ?03
CLC
ADD [AX] , [BX]
JC ?01
CLC
ADD [AX] , DX
JC ?02
MOV DX , 0
INC AX
INC BX
JMP ?00
?01:
ADD [AX] , DX
INC AX
MOV DX , 1
INC BX
JMP ?00
?02:
INC AX
MOV DX , 1
INC BX
JMP ?00
?03:
Multiplying a number by 2
Write a program that implements the operation of multiplying the first of very long number number by 2.
Integers in the range 0 to \(2^{1024}-1\) are represented as 𝑁 ≤ 64 consecutive words of memory each.
Register AX is the address of the first least significant word of the first number, BX=𝑁 is the length of the number.
The result must be in the first number.
MOV AX , 0
MOV DX , 0
?00:
CMP AX , BX
JZ ?02
CLC
ADD [AX] , [AX]
JC ?01
ADD [AX] , DX
MOV DX , 0
INC AX
JMP ?00
?01:
ADD [AX] , DX
INC AX
MOV DX , 1
JMP ?00
?02:
Dividing a number by 2
Write a program that implements the operation of dividing the first of very long number number by 2.
Integers in the range 0 to \(2^{1024}-1\) are represented as 𝑁 ≤ 64 consecutive words of memory each.
Register AX is the address of the first least significant word of the first number, BX=𝑁 is the length of the number.
The result must be in the first number.
The pitfall of this task is that it is possible to use successive RCRs to process the data in order from high to low, but it will destroy the contents of the C flag when determining whether the loop needs to end, so it needs to be specially documented.
CLC
?00:
RCR [BX]
JC ?01
CMP BX , 0
JZ ?10
DEC BX
JMP ?00
?01:
CMP BX , 0
JZ ?10
DEC BX
CMP BX , FFFF
JMP ?00
?10:
Lecture 05
Padovan problem by C
A sequence of integers is read from input using the input.txt file.
Answer (0-no, 1-yes) output to output.txt file
In the case of an empty sequence, an empty file must be created.
\[a_0=1, a_1=1, a_2=1, an=a_{n-2}+a_{n-3}\]#include <stdio.h>
int recurrent(FILE *fin, int a0);
int main(void)
{
FILE *fin, *fout;
fin = fopen("input.txt", "r");
fout = fopen("output.txt", "w");
int a0;
if ((fin != NULL) && (fscanf(fin, "%d", &a0) != EOF))
{
fprintf(fout, "%d", recurrent(fin, a0));
}
fclose(fin);
fclose(fout);
return 0;
}
int recurrent(FILE *fin, int a0)
{
}
Copy the sequence
A sequence of integers in the input stream.
For reading, the inputInt function is used - returning the read number in the EAX register and the Z=1 flag, in case of reading the end of the file.
We need to copy the sequence from the input stream to the output stream.
Functions are used for output.
printiInt - prints the integer contained in the EAX register,
printiEndl - go to another line,
You can also use the printiHex function - prints the hexadecimal representation of the CL register.
All output functions store the values of all registers except the flag registers.
In the case of an empty sequence, the program exit code is -1.
extern printEndl, printInt, inputInt, printHex ; Declare external functions that are used for I/O
%include 'conio.h' ; Include console input/output header
section .text ; Begin the text (code) section of the assembly file
global _start ; Declare the _start label as global so it's visible to the linker
_start: ; The entry point of the program
call inputInt ; Call inputInt to read an integer from standard input
mov rdi,-1 ; Preset rdi with -1, which is potentially used for error signaling
jz .exit ; If zero flag is set (inputInt read EOF), jump to .exit
call printInt ; Call printInt to print the integer in EAX
call printEndl ; Call printEndl to print a newline
.repit: ; Label for the beginning of the loop
call inputInt ; Call inputInt to read the next integer from standard input
jz .exit0 ; If zero flag is set (inputInt read EOF), jump to .exit0
call printInt ; Call printInt to print the integer in EAX
call printEndl ; Call printEndl to print a newline
jmp .repit ; Jump back to the start of the loop
.exit0: ; Label for exiting after printing all integers
xor rdi, rdi ; Clear rdi register (sets the value to 0) to signal successful end
.exit:
mov rax, 60 ; Load the sys_exit system call number into rax
syscall ; Make the system call to exit the program
Maximum of the sequence
A sequence of integers in the input stream.
For reading, the inputInt function is used - returning the read number in the EAX register and the Z=1 flag, in case of reading the end of the file.
We need to find the maximum of the sequence and print the answer to the output stream.
Functions are used for output.
printiInt - prints the integer contained in the EAX register,
printiEndl - go to another line,
You can also use the printiHex function - prints the hexadecimal representation of the CL register.
All output functions store the values of all registers except the flag registers.
In the case of an empty sequence, the program exit code is -1.
extern printEndl, printInt, inputInt, printHex
%include 'conio.h'
section .text
global _start
_start:
call inputInt
jz .emptySequence
mov ebx, eax
.findMaxLoop:
call inputInt
jz .printMax
cmp eax, ebx
jle .findMaxLoop
mov ebx, eax
jmp .findMaxLoop
.printMax:
mov eax, ebx
call printInt
call printEndl
jmp .exit
.emptySequence:
mov rax, 60
mov edi, 255
syscall
.exit:
mov eax, 60
xor edi, edi
syscall
Padovan problem
A sequence of integers in the input stream.
Answer (0-no, 1-yes) to the output stream, is it a Padovan sequence?
In the case of an empty sequence, the program exit code is -1.
\[a_0=1, a_1=1, a_2=1, an=a_{n-2}+a_{n-3}\]One note of caution here, rax must be assigned the value 60 on return.
extern printEndl, printInt, inputInt, printHex
%include 'conio.h'
section .text
global _start
_start:
call inputInt
jz .errexit
cmp eax, 1
jnz .notpad
call inputInt
jz .ispad
cmp eax, 1
jnz .notpad
call inputInt
jz .ispad
cmp eax, 1
jnz .notpad
mov ebx, 1
mov ecx, 1
mov edx, 1
.lp:
call inputInt
jz .ispad
add ebx, ecx
mov r8d, ebx
mov ebx, ecx
mov ecx, edx
mov edx, r8d
cmp eax, edx
jnz .notpad
jmp .lp
.ispad:
mov eax, 1
xor rdi, rdi
call printInt
jmp .exit
.notpad:
mov eax, 0
xor rdi, rdi
call printInt
jmp .exit
.errexit:
mov rdi, -1
mov rax, 60
syscall
.exit:
mov rax, 60
syscall
Missing number
The sequence contains integers from 1 to N in arbitrary order, but one of the numbers is missing (the rest occur exactly once). N is not known in advance. Find the missing number.
A sequence of integers in the input stream.
Answer to the output stream.
IIn the case of an empty sequence, the program exit code is -1.
Since we don’t know how many numbers there are and the order of the series, then we can only determine the number of numbers, then find the series sum if there are no missing numbers, and then subtract the actual series sum to get what the missing numbers are.
extern printEndl, printInt, inputInt, printHex
%include 'conio.h'
section .text
global _start
_start:
call inputInt
jz .errexit
mov ebx, 1
mov ecx, eax
mov edx, 1
.lp:
call inputInt
jz .lpend
add ebx, 1
add edx, ebx
add ecx, eax
jmp .lp
.lpend:
add ebx, 1
add edx, ebx
sub edx, ecx
mov eax, edx
call printInt
jmp .exit
.errexit:
mov rdi, -1
mov rax, 60
syscall
.exit:
xor rdi, rdi
mov rax, 60
syscall
Number - loner
The sequence contains integers from 1 to N. All numbers except one are written twice in random order, one of the numbers is written once. N is not known in advance. Find a number that occurs once.
A sequence of integers in the input stream.
Answer to the output stream.
In the case of an empty sequence, the program exit code is -1.
This task involves multiplication and division, but of course you can add and subtract instead, but it’s too tedious.
extern printEndl, printInt, inputInt, printHex
%include 'conio.h'
section .text
global _start
_start:
call inputInt
jz .errexit
mov ebx, 1
mov ecx, eax
.lp:
call inputInt
jz .endlp
add ebx, 1
add ecx, eax
jmp .lp
.endlp:
mov eax, ebx
mov eax, ecx
add ebx, 1
mov eax, ebx
mov ebx, 2
div ebx
mov ebx, eax
add eax, 1
mul ebx
sub eax, ecx
call printInt
jmp .exit
.errexit:
mov rdi, -1
mov rax, 60
syscall
.exit:
xor rdi, rdi
mov rax, 60
syscall
Find the number
The sequence contains integers, more than half of which are equal to the same number X.
It is necessary to find this number X. It is guaranteed that such a number exists.
A sequence of integers in the input stream.
Answer to the output stream.
In the case of an empty sequence, the program exit code is -1.
This task requires the use of the “Moore’s Vote Algorithm”, the catch being that a number is read before it is judged to be empty, so the initial state of the counter is 1 and not 0.
extern printEndl, printInt, inputInt, printHex
%include 'conio.h'
section .text
global _start
_start:
call inputInt
jz .errexit
mov ecx, eax
mov edx, 1
.lp:
call inputInt
jz .exit
cmp edx, 0
jz .new
cmp ecx, eax
jz .count
sub edx, 1
jmp .lp
.new:
mov ecx, eax
mov edx, 1
jmp .lp
.count:
add edx, 1
jmp .lp
.errexit:
mov rdi, -1
mov rax, 60
syscall
.exit:
xor rdi, rdi
mov eax, ecx
call printInt
mov rax, 60
syscall
Second highest (silver)
The second largest element is the one that becomes the largest element in the sequence after all elements with the highest value have been removed from it.
A sequence of integers in the input stream.
Answer to the output stream.
In the case of an empty sequence, the program exit code is -1.
Negative numbers will appear in the program verification of the task, so the compare operation instruction should only be used with signed comparisons.
extern printEndl, printInt, inputInt, printHex
%include 'conio.h'
section .text
global _start
_start:
call inputInt
jz .errexit
mov ebx, eax
call inputInt
jz .emptyexit
mov ecx, eax
cmp ecx, ebx
jl .lp
mov eax, ebx
mov ebx, ecx
mov ecx, eax
.lp:
call inputInt
jz .ifequ
cmp eax, ebx
jz .lp
jge .s1
cmp eax, ecx
jz .lp
jge .s2
jmp .lp
.s1:
mov ecx, ebx
mov ebx, eax
jmp .lp
.s2:
mov ecx, eax
jmp .lp
.ifequ:
cmp ebx, ecx
jz .emptyexit
jmp .exit
.errexit:
mov rdi, -1
mov rax, 60
syscall
.emptyexit:
mov rdi, 0
mov rax, 60
syscall
.exit:
mov rdi, 0
mov eax, ecx
call printInt
mov rax, 60
syscall
The sum of pairwise products
Find the sum of all pairwise products of a sequence
A sequence of integers in the input stream.
Answer to the output stream.
In the case of an empty sequence, the program exit code is -1.
Assuming that we have only one chance to read the array and we don’t want to request dynamic memory, the problem must be solved in \(O(n)\), and that requires a formula:
\[SUM = \frac{1}{2}((\sum_{i=1}^na_i)^2-\sum_{i=1}^na_i^2)\]
extern printEndl, printInt, inputInt, printHex
%include 'conio.h'
section .text
global _start
_start:
xor ebx, ebx
xor ecx, ecx
call inputInt
jz .errexit
add ebx, eax
mul eax
add ecx, eax
call inputInt
jz .errexit
add ebx, eax
mul eax
add ecx, eax
.lp:
call inputInt
jz .endlp
add ebx, eax
mul eax
add ecx, eax
jmp .lp
.errexit:
mov rdi, -1
mov rax, 60
syscall
.endlp:
mov eax, ebx
mul eax
sub eax, ecx
clc
rcr eax, 1
call printInt
.exit:
mov rdi, 0
mov rax, 60
syscall
Copy array
An array of integers is located in the file input stream. It is required to create an array of N<100 elements and read the array.
You need to copy all array to the output stream.
In the case of an empty sequence, the program exit code is -1.
; External function declarations
extern printEndl, printInt, inputInt, printHex
%include 'conio.h' ; Include the conio.h library for console input-output support
section .bss
A:resd 100 ; Allocate space for an array, defining array A to hold 100 integers
section .text
global _start ; Declare _start as globally visible so that the linker can find the entry point of the program
_start: ; Start of the program
mov ecx,0 ; Initialize counter ecx to 0, for array indexing
mov ebx,A ; Assign the address of array A to ebx, for subsequent read/write operations
.readA: ; Label for reading input
call inputInt ; Call inputInt to read an integer from standard input into eax
jz .eofA ; If the input is 0, jump to .eofA to handle end-of-file condition
mov [A+ecx*4],eax; ; Store the read integer at the corresponding position in array A
inc ecx ; Increase the value of ecx, moving to the next position in the array
jmp .readA ; Jump back to .readA to continue reading the next integer
.eofA: ; Handle end-of-input condition
mov rdi,-1 ; Store -1 in rdi, set as error return code
test ecx,ecx ; Test if ecx is 0 (i.e., if the array is empty)
jz .exit ; If the array is empty, jump directly to .exit to exit the program
mov ebx,A ; Reset ebx to the starting address of array A
.writeA: ; Start writing label
mov eax,[ebx] ; Read the current element from array A into eax
call printInt ; Call printInt to print the value of eax
call printEndl ; Print a newline
add ebx,4 ; Move ebx to the next element in the array
loop .writeA ; Use ecx as a counter to loop through .writeA using the loop instruction
xor rdi, rdi ; Clear rdi, set as success return code
.exit: ; Exit label
mov rax, 60 ; Set rax to 60, corresponding to the sys_exit system call number
syscall ; Perform a system call to exit the program
Sort array
An array of integers is located in the file input stream. It is required to create an array of N<100 elements and read the array.
You need to sort an array of integers in ascending order to the output stream.
In the case of an empty sequence, the program exit code is -1.
; External function declarations
extern printEndl, printInt, inputInt, printHex
%include 'conio.h' ; Includes the conio.h library for console input-output support
section .bss
A:resd 100 ; Reserves space for an array of 100 integers
section .text
global _start ; Declares _start as globally visible, marking the entry point of the program
_start: ; Program start
mov ecx, 0 ; Clears the ecx register, to be used as the array index
mov ebx, A ; Loads the address of array A into ebx for array operations
.readA: ; Start of the loop to read the array
call inputInt ; Calls inputInt function to read an integer from standard input
jz .eofA ; If input is zero, jump to .eofA to handle end of input
mov [A+ecx*4], eax; ; Stores the input integer at the current index position in the array
inc ecx ; Increments index, preparing to read the next value
jmp .readA ; Jumps back to the start of the read loop
.eofA:
mov rdi, -1 ; Sets return error code to -1
test ecx, ecx ; Tests if ecx is zero, i.e., if the array is empty
jz .exit ; If the array is empty, jumps to exit
mov ebx, A ; Resets ebx to point to the start of the array
call _sort ; Calls the _sort function to sort the array
mov ebx, A ; Again sets ebx to point to the start of the array
.writeA: ; Starts the loop to write the array
mov eax, [ebx] ; Reads the current element from the array
call printInt ; Calls printInt to print the current integer
call printEndl ; Calls printEndl to print a newline
add ebx, 4 ; Moves to the next element in the array
loop .writeA ; Continues to output using loop instruction until ecx decrements to zero
xor rdi, rdi ; Clears the rdi register, sets the success return code
.exit:
mov rax, 60 ; Sets rax to 60, corresponding to the sys_exit system call
syscall ; Performs a system call to exit the program
_sort:
pushq ; Saves register state
dec ecx ; Decrement array length by one, preparing for sorting
.?loop1: ; Label for the first loop
push rcx
push rbx
.?loop2: ; Label for the second loop
mov eax, [ebx] ; Takes the current element from the array
cmp eax, [ebx+4] ; Compares it with the next element
jle .?1 ; If the current element is less than or equal to the next, skip swapping
xchg eax, [ebx+4] ; Swaps the two elements
mov [ebx], eax
.?1:
add bx, 4 ; Moves to the next element
loop .?loop2 ; Continues the inner loop
pop rbx
pop rcx
loop .?loop1 ; Continues the outer loop
popq ; Restores register state
ret ; Returns to the calling point
Even strange (Odd)
An array of integers is located in the file input stream. It is required to create an array of N<100 elements and read the array.
You need to output:
- the maximum even element, if the number of even elements is not less than the number of odd ones;
- the maximum odd element, if the number of odd elements is greater than even ones.
For example, for an array of six elements equal to 4, 6, 12, 17, 3, 8, respectively, the answer will be 12 - the largest even number, since there are more even numbers in this array.
Answer to the output stream.
In the case of an empty sequence, the program exit code is -1.
The -2147483648 set here is the smallest negative number that can be stored in a 32-bit register, i.e. it ranges from -2147483648 to 2147483647.
The test instruction is essentially a logical and arithmetic instruction, but it does not save the result of the operation; if the result of the operation is 0, then ZF = 1, for example:
test al, 1 jz even ; If the lowest bit of al is 0, then jump to the even tag and al is an even number test ebx, ebx jz is_zero ; If ebx is 0, jump to is_zero tag
extern printEndl, printInt, inputInt, printHex
%include 'conio.h'
section .bss
A:resd 100 ; space for an array
section .text
global _start
_start:
mov ecx, 0
mov ebx, A
mov edi, -2147483648
mov esi, -2147483648
mov edx, 0
mov ebp, 0
.read_loop:
call inputInt
test eax, eax
jz .finalize
mov [ebx+ecx*4], eax
inc ecx
test eax, 1
jnz .odd_number
.even_number:
inc edx
cmp eax, esi
jle .skip_even
mov esi, eax
jmp .skip_odd
.odd_number:
inc ebp
cmp eax, edi
jle .skip_odd
mov edi, eax
.skip_odd:
.skip_even:
jmp .read_loop
.finalize:
test ecx, ecx
jz .empty_array
cmp ebp, edx
jg .output_odd
.output_even:
mov eax, esi
jmp .output
.output_odd:
mov eax, edi
.output:
call printInt
call printEndl
xor rdi, rdi
jmp .exit_program
.empty_array:
mov rdi, -1
.exit_program:
mov rax, 60
syscall
Enjoy Reading This Article?
Here are some more articles you might like to read next: