News:

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

Why do we use @data.

Started by new_comer, February 10, 2006, 07:40:50 AM

Previous topic - Next topic

new_comer

Hi!

One thing I am trying hard to understand, why do we use @data and LEA or what the hell is PSP(Program Segment Prefix). Why all these are needed when we try to print a string. And all these are not needed while printing a single character.



MichaelW

The PSP is the 256-byte block of memory that precedes a DOS program in memory. For a COM file the PSP is in the same memory block as the program, and for an EXE the PSP is in a separate memory block. DOS uses the first 128 bytes of the PSP to store data that it uses to manage the program, and the second 128 bytes to store the program's command line.

@data is a predefined symbol that resolves to the name of the default data group. It is frequently used in the startup code for a normal EXE to load the segment address of DGROUP into DS and SS. For an EXE, prior to loading DS the program cannot access the data segment because the program loader leaves DS (and ES) pointing to the PSP. Since strings are generally stored in the data segment, you would generally need to load DS before printing a string. No data would be involved when printing a single character that is encoded into the instruction, mov dl,'x' for example.

The LEA (Load Effective Address) instruction "Calculates the effective address (offset) of the source memory operand and stores the result in the destination register." LEA is most commonly used to load the address of a local (stack) variable into a register. You sometimes see LEA used to load the address of a direct memory operand, lea ax,somevar, where somevar is defined in the data segment, for example, but it would usually be better to use the OFFSET operator for this, mov ax,OFFSET somevar for example. LEA can also be used to perform certain types of calculations quickly.
eschew obfuscation

new_comer

Thank you very much for this great piece of information.

But I am curious to know why do we need to use all these while printing a String but but not in case of printing  a character.

I will write a sample code to make my qestion clearer.

The first piece of code takes a character as input and print that on screen. And secode peice of code just print a string.


TITLE Prog1:ECHO PROGRAM

.MODEL SMALL
.STACK 100H
.CODE
MAIN PROC
  MOV AH,2                            ;Display Prompt
  MOV DL,'?'           
  INT 21H

  MOV AH,1                            ;Read Character function
  INT 21H                             ;Character in AL
  MOV BL,AL                           ;Save it in BL

  MOV AH,2                            ;Display Character function
  MOV DL,0DH                          ;Carriage Return
  INT 21H                             ;Execute carriage return

  MOV DL,0AH                          ;Line Feed
  INT 21H

  MOV DL,BL                           ;Retrieve Character
  INT 21H

  MOV AH,4CH                          ;Return to Dos
  INT 21H


MAIN ENDP
END MAIN



Second peice of code:





.MODEL SMALL
.STACK 100H
.DATA
MSG DB 'HELLO World!$'
.CODE
MAIN PROC

  MOV AX,@DATA
  MOV DS,AX

  LEA DX,MSG
  MOV AH,9
  INT 21H

  MOV AH,4CH
  INT 21H

MAIN ENDP
END MAIN

MichaelW

The first program has no defined data. In the second program the DOS Write String function expects the string to be at DS:DX. If DS were still set to the PSP, as the program loader left it, then the function would start displaying the data at the beginning of the PSP rather than at the beginning of the actual string in data segment. As a result the function would display garbage, continuing until it encountered a '$', or until the program (or under real DOS the system) crashed.

eschew obfuscation

new_comer

That was exactly what I needed.

Thanks for clearing my doubt.

Assembly is very fascinating.  :U

Rockphorr

#5
@DATA is predefined name of data segment.
See the reference of SEGMENT and ASSUME directives.

lea AX,string     is equ                  mov AX,offset(string)

but only lea AX,(struc_name PTR[SI]).struc_field

one more ...

mov AX,seg(var_1)
mov DS,AX
lea DX,var_1
;now DS:DX seg:ofs(var_1)

Greets, 
Strike while the iron is hot - Бей утюгом, пока он горячий