Page 1 of 1

movzx

Posted: Sun Jul 20, 2008 3:22 pm
by chezzestix
How does this command behave? I'm having some wonkeyness that I want to attribute to it.

My idea of how it should work:
movzx cx,[prop_cmdlist]

original - 0011 (prop_cmdlist)
extend - 0000 0011 (cx)

Re: movzx

Posted: Sun Jul 20, 2008 3:31 pm
by suthers
it copies whatever you want to copy into the dest, and if the src is smaller than the dest, it filles the rest of the dest with 0's
Jules

Re: movzx

Posted: Sun Jul 20, 2008 4:45 pm
by nick8325
I think you need to do something like
movzx ecx, word ptr [prop_cmdlist]
to get the high 16 bits of ecx zeroed.

EDIT: fix typo.

Re: movzx

Posted: Sun Jul 20, 2008 7:15 pm
by bewing
Uh, no. The size of the source should always be specified, and must always be shorter than the size of the destination register. So movzx 32bit_reg, dword should NEVER work -- it shouldn't even compile.

If the assembler is smart enough, chezzestix' example should work, with the assembler assuming a byte is being moved. But as I said, it really should say movzx cx, byte [prop_cmdlist]
-- but the results should be exactly what you are expecting. cl will be copied, and ch = 0 always.

Re: movzx

Posted: Mon Jul 21, 2008 2:40 am
by nick8325
Sorry, that was a typo! I meant word ptr. :oops:

EDIT: and I think I may have misunderstood chezzestix's example, too. Oh well...

Re: movzx

Posted: Mon Jul 21, 2008 7:58 am
by chezzestix
Well maybe I can get yall to glance at this darn code. It only checks one entry and jumps to no match.

Code: Select all

match_cmd: ;matches user input to a command
       mov ax,0h
       mov cx,0h
       match_matchcmd: ;this sets up the di and si pointers
                mov si,str_promp
                call print ;this just prints a null terminated string pointed to by si
                mov si,temp_cmd
                mov di,cmd_list
                mov cx,ax
                imul cx,8
                add di,cx
                mov al,1
                loop_matchmatchcmd: ;every time this loops around it checks the next letter
                        mov cx,[di]
                        cmp cx,[si]
                        jne dm_matchmatchcmd
                        inc di
                        inc al
                        cmp al,[prop_cmdlist+1]
                        jle loop_matchmatchcmd
                matches_matchmatchcmd: ;if it matches then you call the refenced function
                        mov si,call_list
                        add si,ax
                        call word [si]
                        ret
                dm_matchmatchcmd: ;if it doesnt match inc the command to be checked (ax)
                        inc ax
                        movzx cx,[prop_cmdlist]
                        cmp ax,cx
                        jle match_matchcmd
                        call A000_unrecognized  ;if its greater than the possible commands then none matched
                        ret

prop_cmdlist db 3,8 ;# of comands, max length of command
cmd_list     db "echo    "
             db "hi      "
             db "end     "
call_list    dq A003_echo
             dq A002_greet
             dq A001_end
temp_cmd     db "12345678" ;where the users input for the command is stored
temp         db ?

Re: movzx

Posted: Mon Jul 21, 2008 11:04 pm
by bewing
Hmmmm. I see quite a few things that bother me about this code.

After puzzling over it for awhile, I have gotten the impression that you do not understand that al and ax are the same register. That is, al is the bottom half of ax. You seem to be trying to use al as the index for one loop, and ax as a completely separate index for the other loop. But every time you modify al or ax, you are modifying the other at the same time. If you replace ax with ah in most of this code, it would work much better.

* mov cx,[di] copies TWO bytes into cx, and di is NOT ALIGNED
-- you need to be incrementing di by 2.
* you are never incrementing si -- it should be incremented by 2 after every comparison
* you are jumping to dm_matchmatchcmd, and then trying to do a ret. You can only ret from a call, not a jump. If you do a jump, then you have to jump back. (your code should crash when it hits the ret, right now)
* in matches_matchmatchcmd, you need to be multiplying your "outer index" by 8


Some additional hints:
* you don't need to initialize cx -- it always gets copied from ax
* shl cx, 3 is much more efficient than imul cx, 8 -- and does the same thing in this case

Re: movzx

Posted: Tue Jul 22, 2008 11:03 pm
by chezzestix
Well that fixed alot of issues but there is still something amiss. It will recognize the first command but when it moves to check for the next it gets off base. Its finding 0s (atleast two) somewhere in the memory o sphere. Which are everywhere but where I want the pointer to be... and code to output the memory its checking is long and this project is running out of space fast. Maybe someone can see something in here that I cant.

Code: Select all

match_cmd:
       mov ax,0h
       match_matchcmd:
                mov si,temp_cmd
                mov di,cmd_list
                mov cx,ax
                shl cx,3 ;x8
                add di,cx
                mov ah,1
                loop_matchmatchcmd:
                        mov cx,[di]
                        cmp cx,[si]
                        jne dm_matchmatchcmd
                        add di,2
                        add si,2
                        inc ah
                        cmp ah,[prop_cmdlist+2]
                        jle loop_matchmatchcmd
                matches_matchmatchcmd:
                        mov si,call_list
                        mov ah,0
                        add si,ax
                        call word [si]
                        ret
                dm_matchmatchcmd:
                        mov ah,0
                        inc al
                        call printal
                        cmp al,[prop_cmdlist]
                        jle match_matchcmd
                        call A000_unrecognized
                        ret 

Re: movzx

Posted: Wed Jul 23, 2008 8:02 am
by bewing
Did you change the prop_cmdlist array? Is the byte at [prop_cmdlist+2] equal to 4? It should be. (Or really, prop_cmdlist+1, the way you had it before, was perfectly fine.)

As I said before, the call_list array needs to be indexed by 8 -- not 1. So the matches_matchmatchcmd should say:

Code: Select all

matches_matchmatchcmd:
	mov si,call_list
	movzx cx,al
	shl cx, 3	; x8
	add si,cx
	call [si]
	ret
But as you say, the current code is significantly better than the first try. :wink:

Re: movzx

Posted: Wed Jul 23, 2008 8:25 am
by chezzestix
Even if it is defined as dq? I was under the impression it moved 8 ever time you advanced the pointer.

Yes I did change the prop_cmdlist so it included a 4 at +2 there are other functions that depend on the 8 so I couldnt get rid of it.

Assuming al is the low 8 and ah is the high 8 of ax. Then is my code working when I set ah to 0 if I wanted to keep al by itself?

Example:
01100001 00000011 -ax before
mov ah,0
00000000 00000011 -ax after

Re: movzx

Posted: Wed Jul 23, 2008 1:53 pm
by bewing
Even if it is defined as dq? I was under the impression it moved 8 every time you advanced the pointer.
In C, the compiler knows the size of whatever type of array you are indexing, so for an array of qwords the compiler will multiply the index by 8 for you. Assembly language does not do this. Assembly language always just indexes everything by bytes. You need to increase the size of the index "step" yourself, always. An assembler does not know anything about the concept of "defined". You cannot "define something as dq" in assembler. All that the dq command does is reserve 8 bytes of memory.

In fact, if that is why you have those things in there as dq's, you can get rid of it. Just define them as dw, and then you only have to index by 2.

I hope you are doing something to keep the cmd_list array aligned on a word boundary, since you increased the length of prop_cmdlist.

Your ah / al code works exactly the way you say. It is correct.