RE: code optomization:any way to do this better?

  • From: "Sina Bahram" <sbahram@xxxxxxxxx>
  • To: <programmingblind@xxxxxxxxxxxxx>
  • Date: Mon, 17 Jan 2011 11:27:28 -0500

Ok, so we have:

.loop:
mov EDX, [ECX]
cmp byte [EBX], 0
jne .notnull
.null:

Excellent, you're falling through.

cmp byte [ECX], 0

keep that above comparison in your head. I'm calling it the ECX comp.

je .success
jne .fail

I don't think so ... what did we talk about with falling through. Get rid of 
one of these, and move notnull up.

.notnull:
cmp byte [ECX], 0

wait a minute ... didn't we do this comparison before? Yup, we sure did. It's 
the same ECX comp I wanted us to remember.

je .fail

this tells me that one of these labels can be removed all together, and you can 
simply jump later on into a section. This is where
promoting code comes in. promoting code simply means, take what is common to 
both branches and move it up, and then do the
conditional stuff only.

.check:
cmp [EBX], EDX
jne .fail

.next:
inc EBX
inc ECX

jmp .loop

you can do this with the loop op code, so you don't need to roll your own loop.

.success:
mov EAX,1
jmp .finish
.fail:
mov EAX, 0
.finish:
leave
ret

ok?

Take care,
Sina

-----Original Message-----
From: programmingblind-bounce@xxxxxxxxxxxxx 
[mailto:programmingblind-bounce@xxxxxxxxxxxxx] On Behalf Of Littlefield, Tyler
Sent: Monday, January 17, 2011 11:06 AM
To: programmingblind@xxxxxxxxxxxxx
Subject: Re: code optomization:any way to do this better?

On a side note, here's my code cleaned up, for anyone who cares.
section .text
global _strcmp
_strcmp:
enter 0,0
;we copy our arguments to EBX and ECX
mov EBX, [EBP+8]
mov ECX, [EBP+12]
.loop:
;we need one value in a register
mov EDX, [ECX]
;check for null termination
cmp byte [EBX], 0
jne .notnull
;we have a null termination.
;if the other string is null terminated, we jump to success. otherwise 
it fails because they obviously aren't equal.
.null:
cmp byte [ECX], 0
je .success
jne .fail
;byte wasn't null, now we check for null on the other byte.
;if one is null, it's a fail because again they aren't equal. If it is 
not null, we do another check.
.notnull:
cmp byte [ECX], 0
;not equal, we check for equalness between the two now.
je .fail
;we check for equalness between the two bytes here.
.check:
cmp [EBX], EDX
jne .fail
;here we increase pointers and jump back up to the top of the loop.
.next:
inc EBX
inc ECX
jmp .loop
;strings compared fully
.success:
mov EAX,1
jmp .finish
;strings did not compare fully.
.fail:
mov EAX, 0
;code cleanup.
.finish:
leave
ret

On 1/17/2011 9:03 AM, Littlefield, Tyler wrote:
> OK, a couple questions from your message. I can see letting things 
> fall through, and I actually got rid of a jmp before this. My question 
> is how I should handle this without those paths.
> For example, I need to check the two strings, to make sure that there 
> is something there, or that one of the bytes is not null.
> Last, what do you mean by promote the code up one level?
> Thanks,
> On 1/17/2011 8:48 AM, Sina Bahram wrote:
>> You have to do the same thing that I suggested in my last mail with 
>> your fail and success jumps.
>>
>> Here is a rule. Never, ever, ever, never, ever have two orthogonal 
>> jumps beside one another. You will never have a situation where
>> you need more than one jump, because mathematically, this is 
>> equivalent to this:
>>
>> If(true)
>> Do stuff
>> Else if(false)
>> Do stuff
>>
>> That's redundant, right? Because of course the else is false, there's 
>> no need to check it.
>>
>>
>> Also, you need to promote code up a level, if you'd like less code 
>> space bloat.
>>
>> You compare the byte stored at ECX to 0 in both branches of your 
>> jump, then you jump based on that result. Get rid of it from both
>> branches. In fact, just get rid of those branches all together. There 
>> is no point ot them, since  they contain the same code, before
>> they each individually jump to fail, success, notnull, and null, or 
>> whatever the heck the four paths are.
>>
>> So just collapse all these jumps down.
>>
>>
>> Take care,
>> Sina
>>
>> -----Original Message-----
>> From: programmingblind-bounce@xxxxxxxxxxxxx 
>> [mailto:programmingblind-bounce@xxxxxxxxxxxxx] On Behalf Of 
>> Littlefield, Tyler
>> Sent: Sunday, January 16, 2011 9:56 PM
>> To: programmingblind@xxxxxxxxxxxxx
>> Subject: code optomization:any way to do this better?
>>
>> So I've been playing with assembly a lot lately, and was curious if
>> there was a better way to do this. most importantly, the whole three
>> branched if check (null, not null).
>> section .text
>> global _strcmp
>> _strcmp:
>> enter 0,0
>> ;we copy our arguments to EBX and ECX
>> mov EBX, [EBP+8]
>> mov ECX, [EBP+12]
>> .loop:
>> ;we need one value in a register
>> mov EDX, [ECX]
>> ;check for null termination
>> cmp byte [EBX], 0
>> je .null
>> jne .notnull
>> ;we have a null termination.
>> ;if the other string is null terminated, we jump to success. otherwise
>> it fails because they obviously aren't equal.
>> .null:
>> cmp byte [ECX], 0
>> je .success
>> jne .fail
>> ;byte wasn't null, now we check for null on the other byte.
>> ;if one is null, it's a fail because again they aren't equal. If it is
>> not null, we do another check.
>> .notnull:
>> cmp byte [ECX], 0
>> ;not equal, we check for equalness between the two now.
>> jne .check
>> je .fail
>> ;we check for equalness between the two bytes here.
>> .check:
>> cmp [EBX], EDX
>> je .next
>> jne .fail
>> ;here we increase pointers and jump back up to the top of the loop.
>> .next:
>> inc EBX
>> inc ECX
>> jmp .loop
>> ;strings compared fully
>> .success:
>> mov EAX,1
>> jmp .finish
>> ;strings did not compare fully.
>> .fail:
>> mov EAX, 0
>> ;code cleanup.
>> ;no need for a jmp, it just falls through.
>> .finish:
>> leave
>> ret
>>
>
>


-- 

Thanks,
Ty

__________
View the list's information and change your settings at 
//www.freelists.org/list/programmingblind

__________
View the list's information and change your settings at 
//www.freelists.org/list/programmingblind

Other related posts: