Script started on Thu 29 Feb 2024 12:14:45 PM EST [mweeks@gsuad.gsu.edu@snowball ~]$ echo This is an example of the LOOP command. This is an example of the LOOP command. [mweeks@gsuad.gsu.edu@snowball ~]$ echo Here is a first try: Here is a first try: [mweeks@gsuad.gsu.edu@snowball ~]$ cat array_sum5a.asm ; Assemble: nasm -f elf64 array_sum5a.asm ; Link: gcc array_sum5a.o -o array_sum5a ; Based on code from Irvine's chapter 4. ; This is expanded into a program and adapted for NASM. -MCW extern printf ; We will use this external function section .data ; Data section, initialized variables arrayW: dw 1100h, 2200h, 3300h, 0012h, 0023h, 0034h, 0450h arrayW_length equ ($ - arrayW) / 2 ; Length of the arrayW mystr1: db "The array sum is %x (hex)", 10, 0 mystr2: db "Add array[%d]", 0 mystr3: db " which is %x (hex)", 10, 0 sum: dw 0 tempC: dq 0 section .text global main main: xor rax, rax ; A = 0 mov rcx, arrayW_length ; C = length of arrayW add_another: ;mov rsi, arrayW mov [tempC], rcx ; remember C's value mov rsi, rcx ; print index mov rax, 0 mov rdi, mystr2 call printf mov rcx, [tempC] ; get C's value xor rsi, rsi ;mov esi, [arrayW + ecx] ; print array value mov rsi, [arrayW + rcx] ; print array value mov rax, 0 mov rdi, mystr3 call printf mov rcx, [tempC] ; get C's value mov ax, [sum] ; get the sum so far add ax, word [arrayW + ecx] ; get the word at arrayW[C] mov [sum], ax ; store the sum ; the loop command decrements C, ; and if C != 0, jumps to the target loop add_another mov rsi, rax ; print final sum mov rax, 0 mov rdi, mystr1 ; call printf mov rax, 0 ret [mweeks@gsuad.gsu.edu@snowball ~]$ nasm -f elf64 array_sum5a.asm [mweeks@gsuad.gsu.edu@snowball ~]$ gcc array_sum5a.o -o array_sum5a [mweeks@gsuad.gsu.edu@snowball ~]$ ./array_sum5a Add array[7] which is 34002300 (hex) Add array[6] which is 230012 (hex) Add array[5] which is 23001233 (hex) Add array[4] which is 123300 (hex) Add array[3] which is 12330022 (hex) Add array[2] which is 33002200 (hex) Add array[1] which is 220011 (hex) The array sum is 8a78 (hex) [mweeks@gsuad.gsu.edu@snowball ~]$ echo This output does not make much sense. This output does not make much sense. [mweeks@gsuad.gsu.edu@snowball ~]$ echo The array indices look correct. The array indices look correct. [mweeks@gsuad.gsu.edu@snowball ~]$ echo Notice how it accesses the array from last to first. Notice how it accesses the array from last to first. [mweeks@gsuad.gsu.edu@snowball ~]$ echo You might also notice that it does not access "array[0]", which is a problem that we will deal with later. You might also notice that it does not access array[0], which is a problem that we will deal with later. [mweeks@gsuad.gsu.edu@snowball ~]$ echo But how do we make sense of the array values? But how do we make sense of the array values? [mweeks@gsuad.gsu.edu@snowball ~]$ echo Examine the original definition: Examine the original definition: [mweeks@gsuad.gsu.edu@snowball ~]$ grep "arrayW:" array_sum5a.asm arrayW: dw 1100h, 2200h, 3300h, 0012h, 0023h, 0034h, 0450h [mweeks@gsuad.gsu.edu@snowball ~]$ echo These values are chosen to be easy to verify. These values are chosen to be easy to verify. [mweeks@gsuad.gsu.edu@snowball ~]$ echo We can see these show up in the output, e.g. "12330022" for the array at index 3. We can see these show up in the output, e.g. 12330022 for the array at index 3. [mweeks@gsuad.gsu.edu@snowball ~]$ echo This is a combination of array values at index 3, 2, and 1. This is a combination of array values at index 3, 2, and 1. [mweeks@gsuad.gsu.edu@snowball ~]$ echo index 2 values are reported as "33002200" by the program. index 2 values are reported as 33002200 by the program. [mweeks@gsuad.gsu.edu@snowball ~]$ echo This is a combination of array values at indices 1 and 2. This is a combination of array values at indices 1 and 2. [mweeks@gsuad.gsu.edu@snowball ~]$ echo So the problem appears to be that the values reported are wider than they should be. So the problem appears to be that the values reported are wider than they should be. [mweeks@gsuad.gsu.edu@snowball ~]$ echo Another variation: Another variation: [mweeks@gsuad.gsu.edu@snowball ~]$ cat array_sum5b.asm ; Assemble: nasm -f elf64 array_sum5b.asm ; Link: gcc array_sum5b.o -o array_sum5b ; Based on code from Irvine's chapter 4. ; This is expanded into a program and adapted for NASM. -MCW extern printf ; We will use this external function section .data ; Data section, initialized variables ; Use values that are easy to verify, at least until it works. arrayB: db 01h, 02h, 03h, 04h, 10h, 20h, 30h arrayB_length equ ($ - arrayB) ; Length of the arrayB mystr1: db "The array sum is %x (hex)", 10, 0 mystr2: db "Add array[%d]", 0 mystr3: db " which is %x (hex)", 10, 0 sum: dw 0 tempC: dq 0 section .text global main main: xor rax, rax ; A = 0 mov rcx, arrayB_length ; C = length of arrayB add_another: ;mov rsi, arrayB mov [tempC], rcx ; remember C's value mov rsi, rcx ; print index mov rax, 0 mov rdi, mystr2 call printf mov rcx, [tempC] ; get C's value xor rsi, rsi mov si, [arrayB + ecx - 1] ; print array value and si, 00FFh mov rax, 0 mov rdi, mystr3 call printf mov rcx, [tempC] ; get C's value mov ax, [sum] ; get the sum so far ; Cannot add the value directly, since it adds too wide a value ; add ax, [arrayB + ecx - 1] ; get the word at arrayB[C] ; This should work: ; mov bx, [arrayB + ecx - 1] ; get the word at arrayB[C] ; and bx, 00ffh ; add ax, bx ; This works: add al, [arrayB + ecx - 1] ; get the word at arrayB[C] ; Note that there are several details "swept under the rug" here. ; For example, this mixes different sizes. ; We store the sum as 16 bits. ; We add 8 bits. ; What if the 8 bit result has a carry? ; Notice how this uses "ecx - 1". ; Notice how this works for bytes. If we want this to work ; for words, we would need to double C's value, since an array ; of words would take 2 bytes each. mov [sum], ax ; store the sum ; the loop command decrements C, ; and if C != 0, jumps to the target loop add_another mov rsi, rax ; print final sum mov rax, 0 mov rdi, mystr1 ; call printf mov rax, 0 ret [mweeks@gsuad.gsu.edu@snowball ~]$ nasm -f elf64 array_sum5b.asm [mweeks@gsuad.gsu.edu@snowball ~]$ gcc array_sum5b.o -o array_sum5b [mweeks@gsuad.gsu.edu@snowball ~]$ ./array_sum5b Add array[7] which is 30 (hex) Add array[6] which is 20 (hex) Add array[5] which is 10 (hex) Add array[4] which is 4 (hex) Add array[3] which is 3 (hex) Add array[2] which is 2 (hex) Add array[1] which is 1 (hex) The array sum is 6a (hex) [mweeks@gsuad.gsu.edu@snowball ~]$ echo Notice how this works with bytes instead of words, meaning that we can use C without needing to double the value. Notice how this works with bytes instead of words, meaning that we can use C without needing to double the value. [mweeks@gsuad.gsu.edu@snowball ~]$ echo Also notice how it uses "ecx - 1" to correct the indices. Instead of 7..1, it really uses 6..0. It still reports the indices as +1, but this is easy to fix if we want to. Also notice how it uses ecx - 1 to correct the indices. Instead of 7..1, it really uses 6..0. It still reports the indices as +1, but this is easy to fix if we want to. [mweeks@gsuad.gsu.edu@snowball ~]$ echo Also notice that the values in the array are chosen to be easy to verify. Also notice that the values in the array are chosen to be easy to verify. [mweeks@gsuad.gsu.edu@snowball ~]$ echo You should be able to verify that the sum is correct. You should be able to verify that the sum is correct. [mweeks@gsuad.gsu.edu@snowball ~]$ echo Another detail is that the byte values are ANDed with FF, to isolate the lower 8 bits. Another detail is that the byte values are ANDed with FF, to isolate the lower 8 bits. [mweeks@gsuad.gsu.edu@snowball ~]$ echo The line that says "Cannot add the value directly, since it adds too wide a value" could have the code changed to work The line that says Cannot add the value directly, since it adds too wide a value could have the code changed to work [mweeks@gsuad.gsu.edu@snowball ~]$ echo in a different way. There are usually many ways to get a program to do what we want. in a different way. There are usually many ways to get a program to do what we want. [mweeks@gsuad.gsu.edu@snowball ~]$ exit exit Script done on Thu 29 Feb 2024 12:27:00 PM EST