.386
.model flat,c
.stack 100h

includelib msvcrt

.data
printf proto arg1:ptr byte

pointBuffer byte "Welcome",0
pointBuffer2 byte 12 dup(?),0
.code
public main

main proc
 
  mov ecx,8
  mov esi,offset pointBuffer
  mov edi,offset pointBuffer2
 
while1: cmp ecx,0
        je endloop
mov al,
mov ,al

inc edi
inc esi
dec ecx
cmp ecx,4
jge takepath1
        jmp while1
endloop: nop
takepath1:  invoke printf,addr pointBuffer2
jmp while1
ret
main endp

end main


im trying to do something so simple and i dont see why i cant have a invoke printf in a loop while having an if statment to execute it and jump back into loop

Posted on 2012-06-15 20:57:04 by hellfix
eax, ecx and edx are volatile registers, and are probably being overwritten by the call to printf, breaking your loop.
Posted on 2012-06-16 02:10:19 by Scali
Right. And, in contrast, esi, edi, and ebx are "non-volatile" (esp and ebp too, but we're not concerned with them right now). They need to be "preserved". Hutch didn't like the term "preserved". Let's say: if you alter 'em, you have to put 'em back the way they were, before your function returns. Failure to do so may cause a crash! Might not, but we're "supposed" to do it. (the "proc" and "endproc" macros may do this for you?) Since you're using esi and edi, your choice for a loop counter is pretty obvious. If you have an "abnormal termination", "preserve" 'em!

An alternative would be to push and pop ecx around the call to printf.

Is ".stack 100h" correct in this context?

Best,
Frank

Posted on 2012-06-16 05:53:16 by fbkotler

(the "proc" and "endproc" macros may do this for you?)


Well, yes and no. I believe you have to explicitly specify the registers to save in the 'uses' clause (which depending on your point-of-view is another macro).


Is ".stack 100h" correct in this context?


I don't think it does anything. Normally it would create a .stack segment with the given size. But for 32-bit Windows binaries, the PE loader creates the stack for you. So I'm not sure what will happen. Perhaps the assembler will ignore it... or the assembler will emit a .stack section in the obj file, and the linker ignores it. Or perhaps the linker will link it into the PE file, and the PE loader ignores it...
At any rate, it is not required.
Posted on 2012-06-17 16:19:34 by Scali
Thanks, Scali! Having any luck, Hellfix?

Best,
Frank

Posted on 2012-06-18 08:07:32 by fbkotler
can anyone give me some sample code im still having trouble saving the registers and making a call to printf
Posted on 2012-06-18 15:20:51 by hellfix
Easiest way, probably...

endloop: nop
takepath1:
        push ecx
        invoke printf,addr pointBuffer2
        pop ecx
jmp while1
; need a label here to jump to when ecx=0?
ret  ; never reached?


That should clear up the problem that the call to printf is trashing your ecx. You still don't seem to have an exit condition to your loop.

Does calling your entrypoint "main" imply that this is called by C startup code? If not, "ret" may not provide a clean "ExitProcess". If so, you may still need to "preserve" (push/pop) esi and edi. This appears to be 32-bit code. Why is it in the dos/bios section? I may be confused about what you're trying to do...

Best,
Frank

Posted on 2012-06-18 15:57:31 by fbkotler
im trying to print half of string being processed by the program then print a final message of the copied string heres what i came up with

.386
.model flat,c
.stack 100h

includelib msvcrt

.data
printf proto arg1:ptr byte

pointBuffer byte "Welcome",0
pointBuffer2 byte 12 dup(?),0

.code
public main

main proc
 
  mov ebx,0
  mov esi,offset pointBuffer
  mov edi,offset pointBuffer2
 
while1: cmp ebx,8
        jge endloop
mov al,
mov ,al

inc edi
inc esi
inc ebx

cmp ebx,4
je printOnce

        jmp while1

printOnce: push offset pointBuffer2
call printf

cmp ebx,4
jbe while1

endloop: nop
push offset pointBuffer2
call printf
ret
main endp
end main
Posted on 2012-06-18 16:26:33 by hellfix
First things first... "code tags". Put the word "code" between '[]'s at the beginning of your code and "/code" between '[]'s at the end of your code. The management thanks you. :)


.386
.model flat,c
.stack 100h

includelib msvcrt

.data
printf proto arg1:ptr byte

pointBuffer byte "Welcome",0
pointBuffer2 byte 12 dup(?),0

.code
public main

main proc

I think you'll want that "uses ebx, esi, edi" here. I'm not sure what the syntax is - right after the "proc" or on a separate line? Try it until Masm doesn't complain. :) (or RTFM)

  mov ebx,0
  mov esi,offset pointBuffer
  mov edi,offset pointBuffer2
 
while1: cmp ebx,8
        jge endloop

Strictly speaking, "jge" is for signed comparisons, "jae" is for unsigned. Won't hurt.

  mov al,
  mov ,al
 
  inc edi
  inc esi
  inc ebx

  cmp ebx,4
  je printOnce

Okay... you've copied 3 characters - ebx incremented afterwards, remember. Might want 5 here?

        jmp while1

printOnce: push offset pointBuffer2
  call printf

Caller's responsibility to clean up stack!

  add esp, 4
  cmp ebx,4
  jbe while1

We kinda knew it was 4 (or 5) or we wouldn't be here! An unconditional "jmp" should do here.

endloop: nop 
  push offset pointBuffer2
  call printf
  add esp, 4 ; clean up stack!
  ret
main endp
end main

Outside of not "cleaning up the stack" (removing the parameter) after the call to printf, this doesn't look too bad. Another way to do this would be to "pop" a dummy register (ecx would do, since printf trashes it anyway). Also, I think you want to "preserve" ebx, esi, and edi. "Calling convention"! I think Agner Fog's got a document on it:

http://www.agner.org/optimize/

I'm not able to test this. There may be things I don't see, but I think it'll work. I think it'll print "WelWelcome" - might look better with a newline in there...

Best,
Frank

Posted on 2012-06-18 17:31:20 by fbkotler
This should help

.386
.model flat,c

includelib msvcrt
printf proto arg1:ptr byte

.data

pointBuffer    byte    "Welcome",0
szNewLine      byte    13, 10 ,0
STRLEN          equ $ - pointBuffer

.data?
pointBuffer2    byte    12 dup(?)

.code
public main

main:
    push    esi
    push    edi
    push    ebx
    push    ebp
   
    mov    esi, offset pointBuffer
    mov    edi, offset pointBuffer2

    xor    ebx, ebx
   
    mov    ebp, STRLEN
    shr    ebp, 2
while1:
    mov    al,
    test    al, al
    jz      endloop
   
    mov    , al
    cmp    ebx, ebp
    je      printOnce
    inc    ebx
    jmp    while1

printOnce:
    push    edi
    call    printf
    add    esp, 4 * 1
    inc    ebx
    jmp    while1
 
endloop:
    push    offset szNewLine
    call    printf
    add    esp, 4 * 1
   
    push    edi
    call    printf
    add    esp, 4 * 1
   
    pop    ebp
    pop    ebx
    pop    edi
    pop    esi
    ret
end main
Posted on 2012-06-18 20:42:27 by Gunner