Skip to content

Commit 0b63ccb

Browse files
authored
asm-6: Add additional checks to dot product example (#83)
This commit adds an additional check for the dot product example - check that the given vectors are not empty or print an error message otherwise. Thank you @sevilla-larry for the report. Signed-off-by: Alexander Kuleshov <kuleshovmail@gmail.com>
1 parent 378b9b1 commit 0b63ccb

File tree

2 files changed

+67
-8
lines changed

2 files changed

+67
-8
lines changed

content/asm_6.md

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -239,18 +239,27 @@ section .data
239239
SECOND_INPUT_MSG: db "Input the second vector: "
240240
;; Length of the prompt for the second vector
241241
SECOND_INPUT_MSG_LEN equ 25
242+
242243
;; Error message to print if the number of items in the vectors is not the same.
243-
ERROR_MSG: db "Error: the number of values in vectors should be the same", 0xA, 0
244+
;; `10` is the ASCII code of the new line symbol. `0` is the NUL terminator.
245+
ERROR_MSG: db "Error: the number of values in vectors should be the same", 10, 0
244246
;; Length of the error message.
245247
ERROR_MSG_LEN equ 59
248+
249+
;; Error messge to print if the given vectors are empty.
250+
;; `10` is the ASCII code of the new line symbol. `0` is the NUL terminator.
251+
ERROR_EMPTY_MSG: db "Error: the vectors are empty", 10, 0
252+
;; Length of the error message.
253+
ERROR_EMPTY_MSG_LEN equ 30
254+
246255
;; Format string for the result
247256
PRINTF_FORMAT: db "Dot product = %f", 0xA, 0
248257
```
249258

250259
This is similar to what we defined in our previous programs, but with some differences. First, we will use not only the [sys_write](https://man7.org/linux/man-pages/man2/write.2.html) and [sys_exit](https://man7.org/linux/man-pages/man2/_exit.2.html) system calls, but also [sys_read](https://man7.org/linux/man-pages/man2/read.2.html). We do this because we are going to read user input to build our vectors. Besides the system call identifiers, in the `.data` section definition, we can also see:
251260

252261
- The prompt messages used when asking a user to input data for vectors
253-
- The error message to print
262+
- The error messages to print
254263
- Parameters of the buffer used to store the user input
255264

256265
After defining the data that we can initialize, we need to define uninitialized variables:
@@ -441,9 +450,14 @@ Now we have two buffers with floating-point numbers - `vector_1` and `vector_2`.
441450
;; Prepare to calculate the dot product of the two vectors.
442451
_calculate_dot_product:
443452
;; Check if the number of items in our vectors is equal.
444-
test r14, r15
453+
cmp r14, r15
445454
;; Print an error and exit if not.
446-
jle _error
455+
jne _error
456+
457+
;; Check if vectors are empty.
458+
test r14, r14
459+
;; Print an error and exit if so.
460+
jz _error_empty
447461
448462
;; Set the address of the first vector to the rdi register.
449463
mov rdi, vector_1
@@ -455,7 +469,7 @@ _calculate_dot_product:
455469
call _dot_product
456470
```
457471

458-
Before calculating the dot product of two vectors, we must be sure that both vectors have the same number of components. The number of components of the first vector is stored in the `r14` register, and the number of components of the second vector is stored in the `r15` register. Let’s check if these values are equal; if not, we will print an error message and exit the program. The error-printing and program exit process should already be familiar to you:
472+
Before calculating the dot product of two vectors, we must be sure that both vectors have the same number of components and the given vectors are not empty. The number of components of the first vector is stored in the `r14` register, and the number of components of the second vector is stored in the `r15` register. Let’s check if these values are equal; if not, we will print an error message and exit the program. The error-printing and program exit process should already be familiar to you:
459473

460474
```assembly
461475
;; Print an error and exit.
@@ -483,6 +497,25 @@ _exit:
483497
syscall
484498
```
485499

500+
If the given vectors are empty, we print the following error:
501+
502+
```assembly
503+
;; Print an error and exit.
504+
_error_empty:
505+
;; Set the length of the prompt string to print.
506+
mov rdx, ERROR_EMPTY_MSG_LEN
507+
;; Specify the system call number (1 is `sys_write`).
508+
mov rax, SYS_WRITE
509+
;; Set the first argument of `sys_write` to 1 (`stdout`).
510+
mov rdi, STD_OUT
511+
;; Set the second argument of `sys_write` to the reference of the prompt string to print.
512+
mov rsi, ERROR_EMPTY_MSG
513+
;; Call the `sys_write` system call.
514+
syscall
515+
;; Exit from the program
516+
jmp _exit
517+
```
518+
486519
If both vectors have the same number of components, we can proceed to the calculation. To do that, we store the addresses of both vectors in the `rdi` and `rsi` registers, and put the number of components within the vectors into the `rdx` register. The `_dot_product` function does the main job. Let's take a look at the code of this function:
487520

488521
```assembly

float/dot_product.asm

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,17 @@ section .data
2929
SECOND_INPUT_MSG_LEN equ 25
3030

3131
;; Error message to print if the number of items in the vectors is not the same.
32-
ERROR_MSG: db "Error: the number of values in vectors should be the same", 0xA, 0
32+
;; `10` is the ASCII code of the new line symbol. `0` is the NUL terminator.
33+
ERROR_MSG: db "Error: the number of values in vectors should be the same", 10, 0
3334
;; Length of the error message.
3435
ERROR_MSG_LEN equ 59
3536

37+
;; Error messge to print if the given vectors are empty.
38+
;; `10` is the ASCII code of the new line symbol. `0` is the NUL terminator.
39+
ERROR_EMPTY_MSG: db "Error: the vectors are empty", 10, 0
40+
;; Length of the error message.
41+
ERROR_EMPTY_MSG_LEN equ 30
42+
3643
;; Format string for the result
3744
PRINTF_FORMAT: db "Dot product = %f", 0xA, 0
3845

@@ -227,9 +234,13 @@ _parse_second_float_vector:
227234
;; Prepare to calculate the dot product of the two vectors.
228235
_calculate_dot_product:
229236
;; Check if the number of items in our vectors is equal.
230-
test r14, r15
237+
cmp r14, r15
231238
;; Print an error and exit if not.
232-
jle _error
239+
jne _error
240+
;; Check if vectors are empty.
241+
test r14, r14
242+
;; Print an error and exit if so.
243+
jz _error_empty
233244

234245
;; Set the address of the first vector to the rdi register.
235246
mov rdi, vector_1
@@ -296,6 +307,21 @@ _error:
296307
;; Exit from the program
297308
jmp _exit
298309

310+
;; Print an error and exit.
311+
_error_empty:
312+
;; Set the length of the prompt string to print.
313+
mov rdx, ERROR_EMPTY_MSG_LEN
314+
;; Specify the system call number (1 is `sys_write`).
315+
mov rax, SYS_WRITE
316+
;; Set the first argument of `sys_write` to 1 (`stdout`).
317+
mov rdi, STD_OUT
318+
;; Set the second argument of `sys_write` to the reference of the prompt string to print.
319+
mov rsi, ERROR_EMPTY_MSG
320+
;; Call the `sys_write` system call.
321+
syscall
322+
;; Exit from the program
323+
jmp _exit
324+
299325
;; Exit from the program.
300326
_exit:
301327
;; Specify the number of the system call (60 is `sys_exit`).

0 commit comments

Comments
 (0)