-2

I am trying to put together this assembly language program, and honestly, I am not sure of what I am doing. I tried to look up to some online example. Please assist me and explain to me what each line is does?

Calculate the sum of an array of 10 32-bit integers using loop(s). You may hard-code the input integers. Save the sum in register EAX.

INCLUDE Irvine32.inc    
.data
  arrayVal DWORD 1,2,3,4,5,6,7,8,9,10
  counter = 0
.code
main:    
  xor eax, eax                     
  xor edx, edx                     
  mov ecx, LENGTHOF arrayVal       
L1:
  mov ebx, DWORD arrayVal [edx]    
  add eax, ebx                     
  inc edx                          
loop L1                            

  Call WriteDec                    
  exit
end main
  • memory indexing in asm uses byte offsets. You probably want `arrayVal[edx*4]` for the same reason you're using LENGTHOF instead of SIZEOF. – Peter Cordes Oct 28 '18 at 17:59

1 Answers1

1

I haven't done assembly since college but i will try to explain as much as i remember it might be bit off.

INCLUDE Irvine32.inc 

this line is used to import Irvine32.inc which is required for 32 bit programming.

.data

An assembly programs is made up of multiple sections (memory segments) the data section is used to allocate memory spaces and variables to be used in the subsequent sections

  arrayVal DWORD 1,2,3,4,5,6,7,8,9,10

here we create an array which is 32bit signified by DWORD and initialized with values 1 to 10. With arrayVal pointing to 1.

counter = 0 

We will come to this little later i have doubts about this :P

.code
main:

The code section and main, the above two lines roughly says we are done with declaring variables, all the following stated stuff is instructions you should execute as main function.

Before i explain the other following code you should understand that even though you created memory segments that hold data they can't be used for operations in assembly. you must use special locations called registers for them more info here. edx, eax and ecx are all registers used for special functions.

  xor eax, eax                     
  xor edx, edx   

register basically store binary data, they can have data from old operations before so we reset them to zero by using on xor with themselves.(they are faster than setting them by zero explanation here).

 mov ecx, LENGTHOF arrayVal 

this command basically moves the length of arrayval to the ecx register which is typically used as counter.

So the general logic will be. Read one value store to ebx, add it to eax (our accumalator) and then get next arrayvalue into ebx and add it to ebx and so on and so forth until we have added all values.

L1: and loop L1

the loop is instruction is very special. It basically does two things jump to where we have mentioned in this case L1 and reduce ecx automatically until ecx is zero. and everything in between gets repeated until ecx and hence these lines

  mov ebx, DWORD arrayVal [edx]    
  add eax, ebx                     
  inc edx 

gets executed for all values of array. but this begs the question why do you need counter in the first place in data section(maybe it is a reserved word for ecx i am not sure).

  Call WriteDec                    
  exit

now after adding all the values if you call WriteDec it prints it values from eax register to standard output and we are done . so we exit and end main.

There are some things that seems off and unnecessary but if you google around a bit you should understand more. This seems a good place to start. Maybe read a couple of books, since you seem to be a very fresh beginner.

Shyam Babu
  • 1,069
  • 7
  • 14
  • `counter = 0` defines an assemble-time constant of that name. There aren't any bytes of static storage for it in the `.data` section. You're right that it's completely useless (and that you don't *want* any static storage for it, just a register for your loop counter). And BTW, `loop` is not efficient: [Why is the loop instruction slow? Couldn't Intel have implemented it efficiently?](https://stackoverflow.com/q/35742570). `dec/jnz` is better, or `cmp` on the index (or better use a pointer-increment from a start to end pointer). Or loop an index downwards from the end of the array. – Peter Cordes Oct 28 '18 at 18:32
  • Anyway, you missed the bug here. `arrayVal [edx] ` is a byte offset into a dword array, so this is summing the first 10 (overlapping) 4-byte windows of the buffer, not the first 10 dword elements. – Peter Cordes Oct 28 '18 at 18:38
  • @Jinna: `arrayVal[edx*4]` like I already commented on the question, duh. – Peter Cordes Oct 28 '18 at 20:29
  • @PeterCordes can we do edx + 4 instead of inc edx ? –  Oct 28 '18 at 21:12
  • @Jinna: Yes, using a byte offset instead of scaling an element index with an addressing mode also works perfectly well. Look at C compiler output if you're ever stuck, reading / understanding it is a good way to see how to implement things in asm. [How to remove "noise" from GCC/clang assembly output?](https://stackoverflow.com/q/38552116) shows how: usually compile with `-O1` so the compiler keeps variables in registers. – Peter Cordes Oct 28 '18 at 21:18
  • @PeterCordes thanks you for pointing out the bug, like i said assembly is not my forte . What i remembered i answered :) – Shyam Babu Oct 29 '18 at 07:31