O. I see another issue. Promoting notnull up creates an issue, because I just fall through to .check. having notnull higher requires two branch jumps: 1 for the fail, 1 to jump to check, where it already falls through.
On 1/17/2011 9:37 AM, Littlefield, Tyler wrote:
Sweet, most of it makes sense. Except your ECX comparison comment. I see why double comparisons is bad, and call me slow, but I'm not seeing a way around that to easily. what happens now is it checks for the presence of a NULL byte in string 1, but I needed the equivalent of an or (||), because string a may not be NULL, but string b may be. so it just jumps around based on that. if string a has a null byte, it checks for the presence of such in b, if it has it, voila, we hit the end of an equal string. If not, well... things fail. Not really sure how I'd make this like two branches less, because I need those checks. Thanks for the promotion tip though, that will def help.On 1/17/2011 9:27 AM, Sina Bahram wrote: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 .failI 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], 0wait 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 .failthis 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 theconditional stuff only. .check: cmp [EBX], EDX jne .fail .next: inc EBX inc ECX jmp .loopyou 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, TylerSent: 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