News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Why compiler compiled like this?

Started by stalker, August 10, 2008, 09:51:42 AM

Previous topic - Next topic

stalker

I am sorry for my poor english first,i don't know if i can express myself clearly

see the code below

IsEmpty proc dwOffset:DWORD
    xor ecx,ecx
    cmp byte ptr [dwOffset],0
    je @f
    inc ecx
    @@:
    ret
IsEmpty endp

the procedure is to check if a string is empty

0040101A  /$  55            push    ebp
0040101B  |.  8BEC          mov     ebp, esp
0040101D  |.  33C9          xor     ecx, ecx
0040101F  |.  807D 08 00    cmp     byte ptr [ebp+8], 0
00401023  |.  74 01         je      short 00401026
00401025  |.  41            inc     ecx
00401026  |>  C9            leave
00401027  \.  C2 0400       retn    4

we can see the compiler use [ebp+8] as [dwOffset]
but [ebp+8] = dwOffset,so [dwOffset] should equals [[ebp+8]]

we must modify our code like below,then it can work as we want
IsEmpty proc dwOffset:DWORD
    xor ecx,ecx
    mov eax,dwOffset
    mov al,[eax]
    cmp al,0
    je @f
    inc ecx
    @@:
    ret
IsEmpty endp

0040101A  /$  55            push    ebp
0040101B  |.  8BEC          mov     ebp, esp
0040101D  |.  33C9          xor     ecx, ecx
0040101F  |.  8B45 08       mov     eax, dword ptr [ebp+8]
00401022  |?  8A00          mov     al, byte ptr [eax]
00401024  |?  3C 00         cmp     al, 0
00401026  |>  74 01         je      short 00401029
00401028   ?  41            inc     ecx
00401029   ?  C9            leave
0040102A   $  C2 0400       retn    4
we can see this time the compiler use [ebp+8] as dwOffset correctly

Why the compiler made a mistake in the first time?

PS:I use MASM32 version 9.00 release



hutch--

stalker,

Testing if a string is empty or zero length is very easy. You just test the first byte for zero. Something like this.


mov eax, buffer_address    ; load the address into a register
cmp BYTE PTR [eax], 0      ; compare the 1st byte with zero
je zero                    ; if equal to zero jump to label
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

stalker

OH,Hutch
it seems that you haven't understood me
I want to know why the compiler made the mistake
not how to check a string is empty or not

MichaelW

Quote from: stalker on August 10, 2008, 09:51:42 AM
Why the compiler made a mistake in the first time?

It didn't. For indirect memory operands the address must be stored in a register or registers. For 32-bit code the operand can consist of 1 or 2 registers, a scale factor on one of the registers, and a displacement.

eschew obfuscation

zooba

To further explain MichaelW's answer, Intel x86-based processors are only capable of accessing memory one step (indirection) at a time. You can't use the contents of a memory location to reference another location in one go. [ebp+8] is one indirection (which is okay), [[ebp+8]] would be two (which is not). To achieve what you want, the code would need to look like this:

mov eax, [ebp+8]    ; or mov eax, dwOffset
cmp BYTE PTR [eax], 0


When you define the procedure, dwOffset is effectively equated to [ebp+8]. So by writing [dwOffset], you've actually written [[ebp+8]], which is not possible. MASM simply ignores the extra brackets. Other assemblers behave differently, but this is one of the well known but often overlooked quirks of MASM.

Cheers,

Zooba :U

hutch--

The first example differs from normal only in that it sets the return value in ECX rather than EAX.


; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    include \masm32\include\masm32rt.inc
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

comment * -----------------------------------------------------
                        Build this  template with
                       "CONSOLE ASSEMBLE AND LINK"
        ----------------------------------------------------- *

    iszero PROTO :DWORD

    .code

start:
   
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    call main
    inkey
    exit

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

main proc

    invoke iszero,1

    print str$(ecx),13,10

    ret

main endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

iszero proc pstr:DWORD

    xor ecx, ecx                ; zero ECX
    cmp BYTE PTR [ebp+8], 0     ; test if 1st byte is zero
    je lbl1                     ; if zero return ZERO in ECX
    inc ecx                     ; increment ECX to return 1 if its not
  lbl1:
    ret

iszero endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

end start

00401030                    fn_00401030:                ; Xref 00401027
00401030 55                     push    ebp
00401031 8BEC                   mov     ebp,esp
00401033 33C9                   xor     ecx,ecx
00401035 807D0800               cmp     byte ptr [ebp+8],0
00401039 7401                   jz      loc_0040103C
0040103B 41                     inc     ecx
0040103C                    loc_0040103C:               ; Xref 00401039
0040103C C9                     leave
0040103D C20400                 ret     4
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

stalker

Quote from: zooba on August 10, 2008, 12:18:12 PM
Intel x86-based processors are only capable of accessing memory one step (indirection) at a time.
thank you MichaelW,thank you Rooba,thank Hutch(though you seems haven't understood me still,may caused by my poor expression)
thank you all very much

hutch--

stalker,

I recoded your example for a reason, you mod is not required as a direct memory to immediate comparison is a valid opcode.

You add this,


0040101F  |.  8B45 08       mov     eax, dword ptr [ebp+8]
00401022  |?  8A00          mov     al, byte ptr [eax]
00401024  |?  3C 00         cmp     al, 0


When its not needed, you use the original code that only does a memory comparison as its shorter. It does not have a mistake in it.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

PBrennick

Also,

Hutch's comment about testing for an empty string is merely telling you that your code could be made simpler and faster by not going through all that trouble. You can also test for an empty string in this manner:

    cmp SomeString[0], 0

This is not trying to be critical. When we look at code presented in reference to a question, if we see some simple optimization thing or just a simpler way, we will usually mention it.

For me, it is my "raison de vivre."
-- Paul
The GeneSys Project is available from:
The Repository or My crappy website

stalker

#9
(^_^)