loop instruction zeros cx for some reason

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
alethiophile
Member
Member
Posts: 90
Joined: Sat May 30, 2009 10:28 am

loop instruction zeros cx for some reason

Post by alethiophile »

I have a doubly nested loop that I use to search the FAT root directory for a filename in a bootloader. The code follows:

Code: Select all

.ff_search_loop:
        mov     si,     dx              ;; beginning of string
        mov     di,     bx              ;; entry to search
        push    cx                      ;; save loop counter
        mov     cx,     11              ;; length of filename
.ff_strcmp_loop:
        cmpsb                           ;; compare bytes
        jne     .ff_next                ;; if unequal, try next entry
        loop    .ff_strcmp_loop
        jmp     ff_search_done          ;; if loop finishes, then it matches
.ff_next:
        add     bx,     32              ;; try next entry (32-byte entries)
        pop     cx                      ;; restore original loop counter
        loop    .ff_search_loop         ;; if loop finishes, then not found -- this is the problem

ff_not_found:
        mov     word [ebp - 4], 0xffff  ;; return val: not found
        jmp     ff_done

ff_search_done:
        mov     word [ebp - 4], bx      ;; save entry offset

ff_done:
For some reason, the second loop instruction zeros cx, and hence does not loop, and falls through to the not_found code. Bochs register dump immediately before the instruction:

Code: Select all

eax: 0x00000280 640
ecx: 0x00000200 512
edx: 0x00008f1b 36635
ebx: 0x00009ea0 40608
esp: 0x00009be5 39909
ebp: 0x00009bf9 39929
esi: 0x00008f1c 36636
edi: 0x00009e81 40577
eip: 0x00008d98
eflags 0x00000286
id vip vif ac vm rf nt IOPL=0 of df IF tf SF zf af PF cf
Immediately after:

Code: Select all

eax: 0x00000280 640
ecx: 0x00000000 0
edx: 0x00008f1b 36635
ebx: 0x0000de80 56960
esp: 0x00009be5 39909
ebp: 0x00009bf9 39929
esi: 0x00008f1c 36636
edi: 0x0000de61 56929
eip: 0x00008d9a
eflags 0x00000282
id vip vif ac vm rf nt IOPL=0 of df IF tf SF zf af pf cf
The instruction also messes with the values of bx and di, which are the variables that are changed within the outer loop. Does anyone know why this is happening?

Edit:
Note that it also clears the parity flag; is that relevant?
If I had an OS, there would be a link here.
User avatar
Firestryke31
Member
Member
Posts: 550
Joined: Sat Nov 29, 2008 1:07 pm
Location: Throw a dart at central Texas
Contact:

Re: loop instruction zeros cx for some reason

Post by Firestryke31 »

loop decrements cx and jumps if not zero (IIRC) cmpsb compares ds:si to es:di and increments both (once again, IIRC).

I've found this site very useful for ASM programming.
Owner of Fawkes Software.
Wierd Al wrote: You think your Commodore 64 is really neato,
What kind of chip you got in there, a Dorito?
User avatar
bewing
Member
Member
Posts: 1401
Joined: Wed Feb 07, 2007 1:45 pm
Location: Eugene, OR, US

Re: loop instruction zeros cx for some reason

Post by bewing »

How do you know it's not looping? It sounds like it is looping just fine and simply not finding the specified filename.
User avatar
mintie
Posts: 6
Joined: Wed Jun 03, 2009 8:44 pm
Location: North Carolina, USA

Re: loop instruction zeros cx for some reason

Post by mintie »

Why not just do a repe cmpsb instead of looping around a cmpsb? Something like this should work:

Code: Select all

...
.ff_strcmp_loop:
mov cx, 11
repe cmpsb
jz ff_search_done
...
User avatar
alethiophile
Member
Member
Posts: 90
Joined: Sat May 30, 2009 10:28 am

Re: loop instruction zeros cx for some reason

Post by alethiophile »

OK, there it is. When I type 'n' in bochs, it apparently skips over the entirety of a loop, as it does a function. Seems a dumb behavior. Thanks for the help. Also, I am currently using a double loop because it's simpler; I may switch to a repe at some point, but not now.
If I had an OS, there would be a link here.
User avatar
Troy Martin
Member
Member
Posts: 1686
Joined: Fri Apr 18, 2008 4:40 pm
Location: Langley, Vancouver, BC, Canada
Contact:

Re: loop instruction zeros cx for some reason

Post by Troy Martin »

alethiophile wrote:because it's simpler
Ummm, no, it's really not. One line versus five or six. One line needs no labels, five or more needs multiple. Also takes up an extra 5-10 bytes that could be used for a better bootloader.
Image
Image
Solar wrote:It keeps stunning me how friendly we - as a community - are towards people who start programming "their first OS" who don't even have a solid understanding of pointers, their compiler, or how a OS is structured.
I wish I could add more tex
User avatar
alethiophile
Member
Member
Posts: 90
Joined: Sat May 30, 2009 10:28 am

Re: loop instruction zeros cx for some reason

Post by alethiophile »

OK, because when I first wrote this code, I didn't really understand rep, and since I haven't gotten around to changing it. I'll probably do that now.
If I had an OS, there would be a link here.
egos
Member
Member
Posts: 612
Joined: Fri Nov 16, 2007 1:59 pm

Re: loop instruction zeros cx for some reason

Post by egos »

What strange values of esp and ebp you have. Align stack pointer to 2 or 4 bytes. Why are you using ebp register, but not bp?
If you have seen bad English in my words, tell me what's wrong, please.
Ready4Dis
Member
Member
Posts: 571
Joined: Sat Nov 18, 2006 9:11 am

Re: loop instruction zeros cx for some reason

Post by Ready4Dis »

Also, you are NOT restoring CX to it's original value, and are trashing your stack. Look at your code path if you do a jump to ff_search_done, you never POP CX back to its original value, which means you've left 2-bytes on the stack, that will end up being popped into another variable unkowingly (leaving a nice bug to track down). Using REP will help fix this problem, but you need to be careful with push/pop. These problems tend to show up later on, after you're done testing it by itself and implement it into your other code.
Post Reply