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.
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.
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.