Loops in Assembly - loops

I'm kind of a rookie at programming in Assembly, and I need some clarification on the following kind of loops (##, #B, #F).
When you have a routine like this:
Routine: PROC Value: Byte
MOV ECX, 3
MOVZX EDX, Value
MOV EAX, EDX
##: SHL EAX, 8
OR EAX, EDX
LOOP #B
RET
Routine: ENDP
, what do the ##, #B mean?
As I was told those kinds of loops have some particularities. #B points to the first ## in the routine and #F points to the last ## in the routine, am I right? Is there anything else regarding these loops that I should know of? (I was also told that whenever they appear the loop goes 3 times, but I'm not sure about that).
Thanks in advance.

## is a local label. You can put it on any code line in your program. It is valid until you define the next ## label. (Not the "first" or "last", just previous and next).
#b means "the previously (early source line) defined ## label". #f means "the next defined ## label".
The loop executes three times because the "LOOP" instruction decrements ECX (implicitly) on each iteration, and branches if the remaining value in ECX is not zero... and you loaded ECX with the value of 3 initially.
If you want to understand how the code works, you should assemble it using the MS Assembler, and then single step through it, looking at the registers as you go. Alternatively, read the Intel insturction set manually really carefully. (I did a lot of this when I first started programming the x86, and it was worth every minute, even for that huge document).

Related

Assembly Program to calculate the sum of an array of 10 32-bit integers using loop(s)

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
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.

Assembly language x86 IRVINE infinite loops

I'm new to Assembly language and I need help with an error I keep experiencing, my task in class is to do what I did below, everything I did is correct and how the professor wants it but I can't stop the program from infinite looping, I have the correct answer which is 14 but how do I stop the loop from being infinite without using special commands like ret. How do I stop it?
;Declare an array of words
;Write a loop that adds all the elements of the array located in even places
;Example 3,7,2,8,9
;3+2+9=14
INCLUDE Irvine32.inc
.data
val1 WORD 3,7,2,8,9
.code
main PROC
mov eax, 0
L1:
mov ecx, (LENGTHOF val1)*(TYPE val1+2)-(TYPE val1+4)
mov eax, ecx
call writeDec
loop L1
exit
main ENDP
END main
At the bottom of your loop, you have this instruction:
loop L1
which means "go back to L1."
Loop L1 is a conditional LOOP that is based on the value in ECX. The
real issue is the problem with the value in ECX. LOOP will first
decrement ECX by 1 and compare the new value in ECX with zero. If it
isn't zero it goes to the label (L1). If it is zero it falls through.
Look carefully at where you set the value of ecx. After LOOP decrements ecx by 1 and execution goes to L1, what happens?

PE File Injection

I have some problem with my project. I want insert my code in any program. I explain the situatuion: My program take file (PE type) and start XOR'ed data from First Section to Last Section. Then I download in last section my ASM code, which decodes this data. I marked Last Section like (Write, Execute, Data). My ASM Code:
mov eax, /*I insert address of the beginning of the first section*/
mov ebx, /* I insert orginal EntryPoint (need to use jmp in the end)*/
mov cx, /*I insert number of bytes between Last Section and First*/
DO:
mov ch, [eax]
xor ch,2
mov [eax], ch
inc eax
loop DO
jmp ebx
I repaired VirtualSize, SizeOfRawData (add 24 to everyone + made alignment). Also I changed SizeOfImage and BaseOfCode (here I wrote new address my asm code (pLastSectHeader->Misc.VirtualSize)).
But I have problem when I run my app (which I injected). Help me please with my problem :) I trying make this few weeks.
P.S My code on Plain C + WinAPI http://pastebin.com/Q4EJvM2J
ch is part of ecx so you are overwriting your counter. Also, x86 allows xor with memory operand, so just do xor byte [eax], 2. Furthemore, you should load ecx not just cx because loop uses all of ecx.
Note that if the sections you are trying to decrypt are not marked writable, you are going to run into problems there too.
Learn to use a debugger and next time provide better question than "I have problem when I run my app".

Assembly (MASMx86 PC) duplicating array

I'm working on an encryption project that's got me stumped. I need to apply a series of encryption keys to a string array in order to determine which key was used to encrypt the message. I have the code set up to run a loop which applies all keys within the range, but now i need a way to 'refresh' the original string array. My solution was to copy the original array into a new un-populated array of the same size, for each iteration of the loop. I wrote the following procedure to accomplish this:
CopyBuffer PROC
; Copies the original buffer into a storage variable
; recieves: nothing
; returns: nothing
pushad
mov ecx,67 ; loop counter
mov esi,0
L3:
mov dl,buffer[esi]
mov bufferCopy[esi],dl ; Store byte in array copy
inc esi ; point to the next byte
loop L3
popad
ret
CopyArray ENDP
The arrays referred to in the above code were declared as follows:
buffer BYTE 0e9h,0c8h,0d0h,087h,0ceh,0d4h,087h,0d3h,0cfh,0c2h,087h,0d3h,0ceh,0cah,0c2h,087h
BYTE 0c1h,0c8h,0d5h,087h,0c6h,0cbh,0cbh,087h,0c0h,0c8h,0c8h,0c3h,087h,0cah,0c2h,0c9h
BYTE 087h,0d3h,0c8h,087h,0c4h,0c8h,0cah,0c2h,087h,0d3h,0c8h,087h,0d3h,0cfh,0c2h,087h
BYTE 0c6h,0ceh,0c3h,087h,0c8h,0c1h,087h,0d3h,0cfh,0c2h,0ceh,0d5h,087h,0d7h,0c6h,0d5h
BYTE 0d3h,0deh
bufferCopy db 67 dup(0)
My code successfully populates the duplicate array. However the elements of the copy are different from the corresponding elements of the original array.
I'd really appreciate the wisdom of a more advanced assembly programmer on this one! I'm fairly new to the language, and still a bit fuzzy on syntax.
The code seems to be correct (regardless of its untidy style). The only observation is that the provided sample array has only 66 elements, not 67, so the first byte will be copied twice.
The problem is somewhere else. Try to run the program in the debugger and check the array immediately after the return of the procedure in order to proof its correctness.
Well, it seems
You are not using the loop counter that you have created and your loop is just running forever which in turn overwrites your copyBuffer array.
Try the lines
dec ecx
jnz L3
instedof loop L3 that should help.
Ok, first of all thanks to everyone for your suggestions! I've solved the problem (though probably not in the simplest way possible). First of all, i changed the declaration of bufferCopy from
bufferCopy db 67 dup(0)
to
bufferCopy BYTE SIZEOF buffer DUP(0),0
I think converting to a null terminated string solved some of my problems. Beyond that, i also ammended my CopyBuffer PROC to run as follows:
pushad
mov edx,OFFSET buffer
Call StrLength
mov bufSize,eax
mov ecx,bufSize
mov esi,0
L2:
mov al,buffer[esi]
mov bufferCopy[esi],al
inc esi
loop L2
popad
ret
The call to StrLength was probably a redundancy, considering i knew the length of the string to begin with. As a disclaimer, i'd like to add that i'm not exceptionally familiar with assembly yet. This solution (while functional) is by no means optimal. Furthermore, my explanations are cursory at best.

assembly - accessing array elements

I have an array that I am attempting to print.
I would like to print it out so I can see if it is correct.
It is currently printing the number 1 and stopping. Or, if I mess with the ECX differently it prints out a bunch of zeros and crashes.
Here is my program.
.data
array DWORD 10 DUP(5, 7, 6, 1, 4, 3, 9, 2, 10, 8)
my_size dd 10
sorted DWORD 0
first DWORD 0
second DWORD 0
.code
start:
main proc
cls
mov EBX, offset[array]
mov ECX, [my_size]
dec ECX
sub ESI, ESI
sub EDI, EDI
; print
mov EBX, offset aa
sub ECX, ECX
;mov ECX, my_size
mov ECX, 10
my_loop:
mov EAX, [EBX]
inc EBX
dec ECX
cmp ECX, 0
jle exit_loop
mov first, EAX
print chr$("printing array elements: ")
print str$(first)
loop my_loop
exit_loop:
ret
main endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
end start
I hate to say it, but you're not "ready" to write a bubble sort. Either it's a completely insane homework assignment, or you haven't followed along with the class so far (possibly both).
Very first thing, I don't think you've defined your array correctly. As I read your code, you've got 100 dwords there - 10 copies of the 10 numbers you specify. You shouldn't need "DUP" in there.
I would print the unsorted array first, just to make sure you've got that part right. You appear to be using a couple of macros, there - they sure as heck aren't instructions. Just from the names, I would guess(!) that "print_chr$" prints a single character and "print_str$" prints a string (although you seem to be printing your string and the number 1). If you've got a "print_int$" in your macro set, I would guess(!) that's what you want. Since I'm not familiar with your macros, I could be wrong.
Although you've defined the array as "dword", you only compare a single byte in your sort routine. This probably works for the small numbers you're using, but it isn't really right.
The usual way to do a bubble sort is to set a "flag" (register or variable - this may be what "sorted" is for) to zero at the beginning of each run through the array, and set it to 1 every time you do a swap. When you've done a pass through your array and the flag is still zero - you haven't done a swap - then, and only then, your array is sorted. If you print the array after each pass, you'll see why it's called a "bubble" sort - the smallest/largest number "bubbles up" to its final position.
Your code to walk through a dword array (esi * 4) looks about right (outside of only comparing a byte), but your print routine only increments ebx by one each time through the loop. Either "add ebx, 4" or use "ebx * 4" (not both) to print dwords. Or perhaps your array is only supposed to be bytes?
Seriously, I'd start with something simpler - just print the array - and work up to adding the sort routine after you've got that working.
Hope it helps.
Best,
Frank
I see you've simplified the code. Good idea! I'm still not familiar with the macro you're using, "print_str$". That doesn't "look" to me like it prints a number. Have you got a "print_int$" or similar? If you can get it to print just the first number "5", that would be a good start.
Now... working through your loop, you just "inc ebx". That won't get you the next dword, it'll get you bytes 2, 3, and 4 from the first dword and the first byte from the second dword. Since you used "* 4" in the (removed) sort code, you probably want "[ebx * 4]" here. Either that, or add 4 to ebx each time through the loop. One or the other (but not both) should step through an array of dwords.
I suspect that the first step would be to select the "right" macro to print a number. It'll probably get easier from there(?). Courage! :)
Best,
Frank

Resources