To me, as I understand using labels and ptrs is that they basically do the same thing. What are the differences and why would I use one over another?
A Label is the name given (by you) to an address in your program, this is used in the following manner :-
Label: some code
more code
test eax,1
jne Label
This tells the assembler where to go if the test is not true by replacing Label with an address.
A pointer is a register which contains the address of data which then be accessed in a number of different ways.
Data db 1,2,3,4,5,6,7,8,9
lea esi Data ;esi now contains the address of the start of the data
The data can now be accessed e.g. lodsb which is a string operator
or mov al,[esi+5] which adds an offset
or mov al,[esi+ebx] which adds an offset contained in ebx
There are other ways also.
Yes, that's what I understood about Labels as well (basically a pointer), but then the presentation I was looking at discussed how Labels and PTRs can be used in a similar manner, I think that's what confused me. I'm referring to the label directive. This was the content on that slide:
Assigns an alternate label name and type to an existing storage location
LABEL does not allocate any storage of its own
Removes the need for the PTR operator
and here were a few examples:
dwList LABEL DWORD
wordList LABEL WORD
Quote from: unktehi on February 25, 2009, 04:30:51 PM
... ( basically a pointer )
Hi,
Hummm, ???
This:
.DATA
dwList dd 500
wordList dw 20
Is the same as this:
.DATA
dwList label DWORD
dd 500
wordList label WORD
dw 20
;----------------------------------------------
So, if i want the address of 500 (the pointer) in the esi register i write
mov esi,
offset dwlist
If i want 500 in the register EAX i write
mov eax, dword ptr [dwList]
Or
mov esi, offset dwList
mov eax, dword ptr [esi]
Rui
So what would be the advantage of writing this:
.DATA
dwList dd 500
wordList dw 20
over this? Or vice versus?
.DATA
dwList label DWORD
dd 500
wordList label WORD
dw 20
Think of it this way:
dwList dd 500
mov esi, offset dwlist
In the above, dwlist is a Label and esi is a Pointer to the same labeled location. It is easier to manipulate data using a register but you can do either:
mov al, esi
or
mov al, dwlist[0]
both access the same memory location but when you are using a register you can move around in the data whereas a Label will always point to the one location
inc esi
Usually, I will use the Label method to zero a string but if I am going to change data within the string and the offset is calculated at run-time based upon something you are doing at the time; the Pointer method is a lot more flexible.
Paul
Quote from: PBrennick on February 25, 2009, 08:26:19 PM
It is easier to manipulate data using a register but you can do either:
mov al, esi
Paul,
not mov al, esi but mov al, byte ptr [esi]
because we cannot pass a 32 bit value (in esi) to a 8 bit register (in al) unless we use movzx
Rui
Quote from: unktehi on February 25, 2009, 07:57:30 PM
So what would be the advantage of writing this:
.DATA
dwList dd 500
wordList dw 20
over this? Or vice versus?
.DATA
dwList label DWORD
dd 500
wordList label WORD
dw 20
I dont see any advantage (i use the first ...). Is there any one ?
To get the byte at the address dwList i write mov ..., byte ptr [dwList].
To get the word, mov ..., word ptr [dwList] and to get the dword, mov ..., dword ptr [dwList]
Rui
Ok Thanks guys. I think I understand it. For some reason I was overthinking it - I think I was thinking there was more to it than that.
mov al, byte ptr [esi] byte ptr is not required in this statement, size is implied by al register, it's needed in this case mov [esi],48 will fail mov byte ptr[esi],48 is correct.
QuoteWhat are the differences and why would I use one over another?
Is there a speed and security advantage somewhere? That's why I don't use PTR unless I have to. Never learn all the facts, but I caught the he say once upon a time and never looked back. Seems that even ASM people don't care anymore since CPU is so fast these days.
Quote from: unktehi on February 25, 2009, 07:57:30 PM
So what would be the advantage of writing this:
.DATA
dwList dd 500
wordList dw 20
over this? Or vice versus?
.DATA
dwList label DWORD
dd 500
wordList label WORD
dw 20
Hi,
As I understand it, the LABEL version allows you to
use multiple types on the same memory location/variable.
So you can use the type checking in MASM without
using PTR overrides. So:
VarWord LABEL WORD
VarDoub DD 500
MOV AX,[VarWord]
MOV EAX,[VarDoub]
Regards,
Steve N.
Quote from: FORTRANS on February 26, 2009, 03:04:01 PM
So you can use the type checking in MASM without
using PTR overrides. So:
VarWord LABEL WORD
VarDoub DD 500
MOV AX,[VarWord]
MOV EAX,[VarDoub]
Hi
Steve,
Two names for one variable (VarDoub and VarWord) is it an advantage ?
I will use mov eax, Vardoub or mov ax, word ptr Vardoub
<=> mov eax, dword ptr [Vardoub] , mov ax, word ptr [Vardoub]
Rui
Rui,
Yeah, I made a typo
mov al, [esi]
is all that is needed because al has size and tells the assembler all it needs to know. You do not need 'byte ptr' in this case. But, yes, egg on my face and all that. :U
Paul
Quote from: RuiLoureiro on February 26, 2009, 04:07:34 PM
Hi
Steve,
Two names for one variable (VarDoub and VarWord) is it an advantage ?
I will use mov eax, Vardoub or mov ax, word ptr Vardoub
<=> mov eax, dword ptr [Vardoub] , mov ax, word ptr [Vardoub]
Rui
Hi,
Well, it is an advantage if you don't like to use the PTR overrides.
It is a disadvantage if you want to prevent the type checking from
being subverted. It is available, even if a bit strange. YMMV. It is
probably not advisable to mix up your code and use both forms?
Cheers,
Steve N.
Quote from: FORTRANS on February 27, 2009, 02:32:31 PM
...
It is probably not advisable to mix up your code and use both forms?
Cheers,
Steve N.
Hi Steve,
For me, one name for one variable is too much
and then, i prefer to define variables as dwords
(for true/false i define a dword) and i prefer to use dword ptr [varname]
Instead of mov eax, varname i like to use mov eax, dword ptr [varname]
When or if i want to see what is in the upper word i use word ptr [varname + 2]
etc. etc.
We have problems if we define a variable as a byte and somewhere we use
cmp eax, dword ptr [varname]. Its wrong, of course.
Cheers :U
RuiLoureiro
Many ask this question MANY times since 2001 when masm32 came in kicking butt. This will always be one of the top10 questions forever. So I did another google a minute ago to find old news *like I never did it before. Same tune, new day*.
Wow ... Off the bat, King Google gave this thread Top level with a vs as the LABEL ... that's fast.
http://www.google.com/search?q=ptr+vs+label&hl=en&ie=ISO-8859-1&btnG=Search
Label vs PTR
http://www.masm32.com/board/index.php%3FPHPSESSID%3D79c214658d4afc1361791f92691b68af%26topic%3D10938.0 - 38k -
Anyway, who need type checking if you are an assembler who knows how to write your own secure code. Type checking only slow thing down because it want to HELP you or itself.
I verified this though saved pages on my HD, it was Qage who said this and I never forgot his line: NOTHING IS FASTER THAN A JUMP
I agree with RuiLoureiro, use ALL form with-in in your code for personal reference and proof of concept. It cost you NOTHING these days. Why worry. This is not 1993.
So now you know why: If you need help use type checking and PTR and all those other goodies that masm want to give you but if you choose to do things for yourself, as what a true assembler is suppose to be all about, I got one thing to say... "HAVE A NICE FLIGHT" and don't meet me there, beat me there ... if you can. hee hee
QuoteWe have problems if we define a variable as a byte and somewhere we use
cmp eax, dword ptr [varname]. Its wrong, of course.
That is an override; it is NOT wrong nor will it cause problems as long as you consider the endian situation.
Paul
Quote We have problems if we define a variable as a byte and somewhere we use
cmp eax, dword ptr [varname]. Its wrong, of course.
That is an override; it is NOT wrong nor will it cause problems as long as you consider the endian situation.
Paul
Hi Paul, :U
we cannot use
dword ptr or
word ptr if we define a variable as a BYTE.
Read an run this:
the solution is correct but we get «There is no solution»
Quote
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««
include \masm32\include\masm32rt.inc
.586
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««
.data
Val1 dd 5
Val2 dd 6
Sum db ? ; variable is BYTE
Junk dd 33333333h
.code
; ####################################
start:
push Val2 ; = 6
push Val1 ; = 5
call TwoAdd
; »»»»»»»»»»»»»
; The Sum is 11
; »»»»»»»»»»»»»
cmp dword ptr [Sum], 11 ; we cannto use DWORD PTR
jne short @F
print ustr$(eax)
print chr$(13, 10)
inkey "Thats the solution..."
exit
@@: print ustr$(eax)
print chr$(13, 10)
inkey "There is no solution..."
exit
;----------------------------------------------------
TwoAdd proc
push ebp
mov ebp, esp
mov eax, [ebp+8] ; val1
add eax, [ebp+12] ; val2
mov [Sum], al
pop ebp
ret 8
TwoAdd endp
; «««««««««««««««««««««««««««««««««««««««««««««
end start
Rui
Quotewe cannot use dword ptr or word ptr if we define a variable as a BYTE
This would be a problem with the number of elements in the variable, not with the type of the variable. For example:
variable db 4 dup(0)
This would work for either access, the TYPE operator would return 1, and the SIZEOF operator would return 4.
... which means I am correct and your code needs to be adjusted. I am NOT saying it is a good idea or a bad idea. All I am saying is that we all do that all the time to move data quickly in blocks instead of bytes. A lot of string copy routines use overrides and because there is no type checking it will always work. But as I stated before, there CAN be an endian problem but, if there is, it is the fault of the programmer.
Paul
Quotewe cannot use dword ptr or word ptr if we define a variable as a BYTE
For example:
variable db 4 dup(0)
Quote
MichaelW,
Yes i know, but thats not the problem. The problem is with the code
i posted before. So, my example doesnt need to be adjusted. The example
shows what it shows, Paul. When
i define a variable as a dword
i use it
as a dword and not as a byte and when
i define a variable as a byte
i use
it as a byte and not as a word or dword.
With variable
defined as 4 bytes we can access as we want. As byte, as word, as dword, etc. It depends ...
When i use a name like variable it stands for an address for 4 bytes like
when i used Sum but now for 1 byte only
Rui
Before it gets too ideological, here a very practical example (just imagine that "version" sits in an include file that you don't really want to open). I vaguely remember some hll dialects call that a UNION.
include \masm32\include\masm32rt.inc
.code
v4 LABEL dword ; a 32 bit integer
version db "Ver3.dll", 0 ; a string
start:
.if v4=="2reV"
MsgBox 0, offset version, "This is the second version of my dll:", MB_OK
.elseif v4=="3reV"
MsgBox 0, offset version, "This is the third version of my dll:", MB_OK
.else
MsgBox 0, offset version, "Unknown version: ", MB_OK
.endif
exit
end start
Quote
Before it gets too ideological, here a very practical example ...
Hi jj2007,
In this particular case, it does the same, but
v4 is better than
dword ptrQuote
include \masm32\include\masm32rt.inc
.code
;v4 LABEL dword ; a 32 bit integer
version db "Ver3.dll", 0 ; version is a string
start:
.if dword ptr version =="2reV"
MsgBox 0, offset version, "This is the second version of my dll:", MB_OK
.elseif dword ptr version =="3reV"
MsgBox 0, offset version, "This is the third version of my dll:", MB_OK
.else
MsgBox 0, offset version, "Unknown version: ", MB_OK
.endif
exit
end start
Another version
Quote
; «««««««««««««««««««««««««««««««««««««««««««
include \masm32\include\masm32rt.inc
.586
.code
version db "Ver2.dll", 0 ; a string
start:
.if byte ptr [version + 3]=="2"
MsgBox 0, offset version, "This is the second version of my dll:", MB_OK
.elseif byte ptr [version + 3]=="3"
MsgBox 0, offset version, "This is the third version of my dll:", MB_OK
.else
MsgBox 0, offset version, "Unknown version: ", MB_OK
.endif
exit
end start
Rui :U
Good luck with your programming Rui.
Paul
Hi Rui,
It's a matter of terminology. Without looking closely at the previous posts, I assumed that the uppercase BYTE was a type specifier, so I interpreted "define a variable as a BYTE" as "define a variable of type BYTE (which could be a byte array)". You apparently meant it as "define a variable as a single byte", and for that you are right, accessing that single byte as some other size will not work.