Hello I am new to assembly and I’m struggling to get a two-part program to work. I am using Visual Studio for this x86 assembly.
Part I)
My first goal is to count up to 13, adding each value on the way there. Ex, 0+1+2+3…+13=91. I want to store that total in totall.
Part 2)
Secondly, I want to count up by the powers of 2 from 2^0 to 2^6. Ex, 0,1,2,4,8,32,64.
I think* I am doing that but I am not storing each value as I go. I want to store these in consecutive memory locations.
I have this so far,
.586
.MODEL FLAT
.STACK 4096
.DATA
num1 BYTE 13 ;Initialize number to count to
totall BYTE 0 ;Total of all counted numbers
temp BYTE 0 ;Temp for loop adding
shiftme BYTE 1 ;Start of counting 2^0 so I can reach 2^6
.CODE
main PROC
;code here
increment: ;Increment label
inc temp ;Increment temp by 1
mov eax, temp
add totall, eax ;Add temp+totall and store in totall
cmp eax, num1 ;Compare for jump
jne increment ;Jump if not equal
;this part should store each value 1,2,4,8,32.. in consecutive memory locat
shiftallthethings: ;Shift label
shl shiftme, 1 ;Shifting bits to the left one
cmp shiftme, 64 ;Comparing for the jump
jne shiftallthethings ;Jump if not equal to
ret
main ENDP
END
Questions to help me understand.
- How does one store values in consecutive memory locations?
- Am I using the jump and label instructions correctly?
- Do I need to use specific registers like eax to perform these problems? Why?
Any help is GREATLY appreciated, thanks.
First of all, in answer to your questions:
In MASM32, you can either directly do a
movlikemov sum_addr, eax(as long as the data types have the same size) or you can pass around data pointers. In the example I wrote, a pointer tototalis passed to the function. The function then writes a value to the memory pointed to by that pointer (i.e. contents oftotal). Not quite sure what you mean by consecutive memory locations. If you mean pointer arithmetic, I can show you an example of that too.Yes, that seems to be fine. An alternative which I have use is anonymous labels. This is appropriate when the label is trivial and is fairly close by. It’s personal preference. If you feel a label name is more appropriate, feel free to use that too.
MASM32 follows the call convention of Win32 (stdcall), so it’s good for you to do that too. In terms of register preservation, it means that all functions are expected to preserve registers except for
eax,ecxandedxwhich are deemed trashable. Return values are stored ineaxoreaxandedxif more than 4 bytes is required.In terms of the code you have written, you have a few problems such as attempting to move different size data types into each other. For example, if you move a
byteinto adword, you must extend it to be of the same size first.That will not compile because
tempis only 1 byte long, whereaseaxis 4 bytes. You could do instead:This zero-extends
tempbefore doing the move. Here is some code I’ve thrown together which might teach you a few things. It uses macros (not sure if you want to learn those yet), but otherwise demonstrates idiomatic MASM32 parameter passing and return values.The code is not optimised but should be easily understandable. Notice how I have tried to use registers as much as possible (this is more efficient than constantly dealing with memory if we have enough registers).