News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Odd behavior using PTR. Any suggestions?

Started by mmwatson, November 17, 2010, 03:18:26 AM

Previous topic - Next topic

mmwatson

Greetings,

I am trying to learn MASM using Kip Irvine's Assembly Language for x86 processors (6th edition) and have encountered something with the PTR command I can't explain. I'm hoping someone who's already worked with ptrs can either explain what's going on, or else point me toward some supplementary reading that might help.

I am trying to use PTR to store a variable of size BYTE in a 32-bit register (I know that I can do this by using MOVZX or by simply storing my byte variable into AL instead of eax, but from what I read, I'm supposed to be able to "coerce" eax into accepting a byte using PTR).

This works fine as long as store only *one* variable into eax. If I try to do several in succession, I find that only the last byte variable I declared in my data section displays properly. I feel certain that I'm overlooking something really basic, but I haven't been able to figure out what.

Here's the source code of a program that illustrates this behavior. I hope it isn't considered bad form to post something that requires a particular library such as Irvine32.inc.

TITLE Peculiar Ptrs (peculiarPtrs.asm)

; Description: Demonstrates an odd behavior when using the PTR command to put
;      a variable of size BYTE into a 32-bit register.
; Author: Michael Watson
; Revision date: 11/13/2010

INCLUDE Irvine32.inc
.data
byte_1   byte   11
byte_2   byte   22
byte_3   byte   33

.code
main PROC   
   mov   eax,0   ; clear out contents of eax
   mov   eax,dword ptr [byte_1]
   call   WriteDec ; should output 11 but outputs garbage
   call   crlf
   
   mov   eax,0   ; clear out contents of eax
   mov   eax,dword ptr [byte_2]
   call   WriteDec ; should output 22 but outputs garbage
   call   crlf   

   mov   eax,0   ; clear out contents of eax
   mov   eax,dword ptr [byte_3]
   call   WriteDec ; Outputs 33
   call   crlf

   ; HOWEVER, if you change the order in which byte_1, byte_2 and
   ; byte_3 are declared in the .data section, you find that
   ; the LAST one that's declared is always the one that's output
   ; properly. The others are output as garbage.
   exit
main ENDP

END main


oex

Quote from: mmwatson on November 17, 2010, 03:18:26 AM
If I try to do several in succession, I find that only the last byte variable I declared in my data section displays properly.

mov esi, alloc(32)

mov al, BYTE PTR [esi]
mov ah, BYTE PTR [esi+1]
bswap
mov al, BYTE PTR [esi+2]
mov ah, BYTE PTR [esi+3]

I'm not quite sure what you are asking but it is cleared when you:
mov eax, 0
We are all of us insane, just to varying degrees and intelligently balanced through networking

http://www.hereford.tv

donkey

The problem is that you are not zero extending your BYTE size data. When you move it as a DWORD into EAX it will also move the 3 BYTEs following it (a DWORD). The third BYTE data has nothing after it so it will appear correct, the second will be 0160Bh (5643) and the first will be 021160Bh (2168331). You can use the program but you should be blanking the three high bytes of EAX by ANDing it with 0FFh:

MOV EAX,DWORD PTR [byte_x]
AND EAX,0FFh

Alternatively you can use MOVZX (mov zero extended) however in that case you have to lose the DWORD PTR since you are only moving a BYTE.

MOVZX EAX, [byte_x]

Edgar
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

RuiLoureiro

Quote from: mmwatson on November 17, 2010, 03:18:26 AM
;INCLUDE Irvine32.inc
.data
byte_1   byte   11
byte_2   byte   22
byte_3   byte   33

.code
main PROC   
   mov   eax,0   ; clear out contents of eax
   mov   eax,dword ptr [byte_1]
   call   WriteDec ; should output 11 but outputs garbage
                 ....

Michael Watson,

   mov   eax,0   ; clear out contents of eax            <- it does nothing !!!
   mov   eax, dword ptr [byte_1]                     .<-you are moving a dword not a byte

   is wrong, so «call   WriteDec» will output garbage  - correct

   if you want to move a byte to a 32 bit register repalce it by

   movzx    eax, byte ptr byte_1
   and then call WriteDec ...

mmwatson

Thanks to you all. This helps, I think I've got an inkling why it was behaving so strangely now. I'll play with it a bit more using the techniques you all suggested.

MW