Public Group

# [Assembly] Loops and input problems?

This topic is 2854 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I just started learning assembly (for fun) and i have 2 problems.

The first is that this generates an 'infinite' loop instead of just looping 5 times:

include '%fasminc%/win32ax.inc'.data  inchar     DB ?  numwritten DD ?  numread    DD ?  outhandle  DD ?  inhandle   DD ?  string1    DB "Hello World!".code  start:        invoke  AllocConsole        invoke  GetStdHandle,STD_OUTPUT_HANDLE        mov [outhandle],eax        invoke  GetStdHandle,STD_INPUT_HANDLE        mov [inhandle],eax        MOV ECX,5        loop1:           invoke  WriteConsole,[outhandle],string1,12,numwritten,0        LOOP loop1        invoke  ReadConsole,[inhandle],inchar,1,numread,0        invoke  ExitProcess,0.end start

Second problem is that i can't seem to be able to get input twice. With this program, the second ReadConsole doesn't seem to be executing.
include '%fasminc%/win32ax.inc'.data  inchar     DB ?  numread    DD ?  inhandle   DD ?.code  start:        invoke  AllocConsole        invoke  GetStdHandle,STD_INPUT_HANDLE        mov [inhandle],eax        invoke  ReadConsole,[inhandle],inchar,1,numread,0        invoke  ReadConsole,[inhandle],inchar,1,numread,0        invoke  ExitProcess,0.end start

Oh and one more question, what does the %fasminc% in this line of code do? Is it specific to the FASM assembler i'm using?
include '%fasminc%/win32ax.inc'

##### Share on other sites
I would guess that %fasminc% refers to the FASM include folder. Something like %WINDIR% for the Windows directory.

##### Share on other sites
Regarding your first problem. It looks like it should work. Try changing the "loopl" label into something more obviously a label. "loopl" is very close to looking like the loop instruction itself.

loop_label:
loop_start:
loop_top:

##### Share on other sites
Nope, still doesn't work.

##### Share on other sites
You are setting up a loop counter, but you aren't actually counting iterations or comparing to the counter or anything.

##### Share on other sites
Does "invoke" trash ecx?

##### Share on other sites
where are you testing for if your loop needs to be exited?

basically

put value 5 in register ecx

looplabel
write this to console
loop to looplable

##### Share on other sites
Quote:
 Original post by ZahlmanYou are setting up a loop counter, but you aren't actually counting iterations or comparing to the counter or anything.

That's built into the LOOP instruction.

From the Intel docs:

Quote:
 LOOP/LOOPcc - Loop according to ECX counterPerforms a loop operation using the ECX or CX register as a counter. Each time the LOOP instruction is executed, the count register is decremented, then checked for 0. If the count is 0, the loop is terminated and program execution continues with the instruction following the LOOP instruction. If the count is not zero, a near jump is performed to the destination (target) operand which is presumably the instruction at the beginning of the loop. If the address-size attribute is 32 bits, the ECX register is used as the count register. Otherwise, the CX register is used.

So, one cause for an infinite loop might be that ECX is getting trashed by "invoke", that is, the count is being replaced with a garbage value.

Try setting ECX to 1 and see what happens. If you still get an infinite loop, then ECX is getting trashed somewhere in between. If not then try 2, then 3, then 4, then 5 to see if the problem results somewhere along the way.

##### Share on other sites
EAX, ECX, and EDX are not saved by the callee in most calling conventions. EBX, ESI, EDI and EBP are supposed to be preserved by most calling conventions.

I examined some of the assembly within _WriteConsoleA@20 and functions it calls. It definitely overwrites ECX without saving/restoring it.

The easiest fix is to replace your loop by using EDI, DEC, and JNZ manually.

  MOV EDI, 5label:  WriteConsole(...)  DEC EDI  JNZ label

[Edited by - Nypyren on August 26, 2010 3:10:16 PM]

##### Share on other sites
Quote:
 Original Post by LessBreadSo, one cause for an infinite loop might be that ECX is getting trashed by "invoke", that is, the count is being replaced with a garbage value.Try setting ECX to 1 and see what happens. If you still get an infinite loop, then ECX is getting trashed somewhere in between. If not then try 2, then 3, then 4, then 5 to see if the problem results somewhere along the way

Tried them all, still got an infinite loop. Why would "invoke" trash a register?

Quote:
 Original post by NypyrenEAX, ECX, and EDX are not saved by the callee in most calling conventions. EBX, ESI, EDI and EBP are supposed to be preserved by most calling conventions.I examined some of the assembly within _WriteConsoleA@20 and functions it calls. It definitely overwrites ECX without saving/restoring it.The easiest fix is to replace your loop by using EDI, DEC, and JNZ manually. MOV EDI, 5label: WriteConsole(...) DEC EDI JNZ label

Hey that worked! Thanks :) One question though. This code basically means:
  fill EDI with the value 5label:  WriteConsole(...)  Decrease EDI by 1  Jump to label

So how does JNZ know when to stop?
Google gave me that "JNE (JNZ) jumps if it is not equal or zero."
???

Thanks for the help. Anyone knows the solution to the second problem? Assembly is so confusing :(

[Edited by - Waaayoff on August 27, 2010 1:36:07 AM]

• 10
• 48
• 12
• 10
• 10
• ### Forum Statistics

• Total Topics
631383
• Total Posts
2999680
×