News:

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

assembly syntax

Started by xxxx, February 06, 2005, 09:06:29 AM

Previous topic - Next topic

xxxx

what is the difference between these two instructions?DATA_IN is a string of acsii that the user inputs.therefore the length of the string would be stored in the 2nd byte right?my intention was to store the length of the string into CX.i intially tha that these two were the same but apparently they aren't.







1.     MOV CX,BYTE PTR [OFFSET DATA_IN+1]


2.     MOV BX,BYTE PTR OFFSET DATA_IN
        MOV CL,[BX+1]

MichaelW

If you are using the DOS Buffered Input function (0Ah), then from Ralf Brown's Interrupt List, the format of the input buffer is:

Quote
Offset   Size   Description   (Table 01344)
00h   BYTE   maximum characters buffer can hold
01h   BYTE        (call) number of chars from last input which may be recalled
                          (ret) number of characters actually read, excluding CR
02h  N BYTEs     actual characters read, including the final carriage return

So the length of the buffer is stored in the first byte and the length of the returned string in the second byte.

In the position you are using it the PTR operator is used to specify an operand size for indirect memory operands where MASM cannot otherwise determine the operand size, or to "operate on data in a size other than the size originally declared". OFFSET DATA_IN+1 is not a memory operand -- it is a constant, so the PTR operator is inappropriate. You could get the length of the returned string into CL by either of these methods:

MOV CL,DATA_IN+1

MOV BX,OFFSET DATA_IN
MOV CL,[BX+1]

For which MASM generates this code:

0B43:0000 8A0E1900      MOV     CL,[0019]
0B43:0004 BB1800        MOV     BX,0018
0B43:0007 8A4F01        MOV     CL,[BX+01]

The brackets around the [0019] are used by the disassembler (DEBUG in this case) to indicate a direct memory operand. Note that MASM will not allow you to specify a direct memory operand in this manner.


eschew obfuscation

xxxx

#2
yes i am  using the DOS Buffered Input function (0Ah).now i have a few more questions that i hope you could answer



1.given that BX is a 16-bit register and DATA_IN is a byte ,what happens when :  MOV BX,OFFSET DATA_IN   ?
  does BX get filled with 2 addreses from DATA_IN as in :

  BH=OFFSET DATA_IN+1
  BL=OFFSET DATA_IN+0

  or does only BL gets filled with the starting address of DATA_IN while BH is emty?

2.why does this generate an error?
   
    MOV CL,OFFSET DATA_IN

3.regarding PTR

assume :
   
     DATA_IN  dw 1223H,2345H
     
   then would there be any difference between:
     
i.     MOV BX,OFFSET DATA_IN
ii.     MOV BX,BYTE PTR DATA_IN
     
4.could you provide a few simple examples where a PTR is appropriate?

5.i know that you can't move data between registers that are of different sizes so why  does this not generate an error?
   

     MOV CL,[BX+1]

6.if the following stores the length of the string into CL:
   
   MOV BX,OFFSET DATA_IN
   MOV CL,[BX+1]

   what is stored in CL if :
   
    MOV CX, [OFFSET DATA_IN+1]






sorry if my questions are silly but i'm a newbie so bear with me.
thanks
       






MichaelW

1.
For a 16-bit program the segment word size is 16 bits, so the offset addresses are 16-bit values, so BX gets loaded with the 16-bit offset address of DATA_IN.

2.
Because a 16-bit address will not fit in an 8-bit register.

3.
Yes, a big difference. The first instruction would load BX with the 16-bit offset address of DATA_IN. The second instruction would return  "error A2070: invalid instruction operands" because it is trying to move a byte into a word register. If you changed the instruction to MOV BX,DATA_IN, it would move the first word of DATA_IN into BX.

4.
MOV AX, WORD PTR DATA_IN (if DATA_IN was originally declared as a byte variable)
MOV AL, BYTE PTR DATA_IN (if DATA_IN was originally declared as a word variable)
MOV BYTE PTR[BX], 123 (because MASM cannot tell what data size BX is pointing to)

5.
Because MASM is assuming from the register size that BX is pointing to a byte, so it encodes the instruction on that basis. You also would not get an error for MOV DATA_IN,1234 because MASM would assume from the declared size of DATA_IN that it needs to encode the instruction to take a 16-bit immediate value as the source operand. Perhaps I should add that the instructions must be encoded to specify exactly what the instruction is to do, and this includes the size of the data that the instruction is to operate on. You also cannot move between a register and a memory operand (variable) if the two are different sizes (see answer 4).

6.
The low (least significant) byte of (the offset address of DATA_IN +1).

eschew obfuscation

xxxx

6.
The low (least significant) byte of (the offset address of DATA_IN +1).

is it the contents of the address or the address  itself?

MichaelW

The offset address itself.

Here is a batch file and a test app that should make it easier for you to answer these sorts of questions for yourself. I used a tiny memory model to reduce complications. The batch file will generate as assembly listing and a map file. If no errors are encountered in the assembling and linking process it will start DEBUG and load the program into it. You can then enter the Unassemble (U) command to see an unassembled listing of the first part of the program code. If you keep the code short you will be able to see all of it after the first Unassemble command. Otherwise, enter additional Unassemble commands to see more of the program code. You can trace through the instructions one at a time with the Trace command (T), but note that the Trace command will trace into the BIOS and DOS functions calls, so you may want to step over the function calls with a Proceed (P) command. You can run the program with a Go (G) command. You can see the program's current register values with a Register command, or exit from DEBUG with the Quit (Q) command.

I assumed ML and a 16-bit linker named LINK16 are in the same folder as the batch file and the source file.

In the old days, it was very common for programmers learning assembler to use the DOS DEBUG program. MASM makes a much better assembler, but DEBUG is still useful for debugging and experimenting with 16-bit code. I already provided this link to a DEBUG tutorial:

http://www.old.masmforum.com/viewtopic.php?t=4051


@echo off

if exist test.obj del test.obj
if exist test.exe del test.com

ML /Fl /Sa /c test.asm

if exist test.obj goto asm_ok
goto err

:asm_ok

LINK16 /MAP /LINE /TINY test.obj,test.com;

if exist test.com goto link_ok
goto err

:link_ok

debug test.com

:err
pause


    .model tiny
    .stack
    .data
      wvar dw 'ww','ww','ww'
      bvar db "bbb"   
    .code
    org 100h
start:   
; =========================================================
    mov bx,offset bvar
    mov al,[bx+1]
    mov bx,offset wvar
    mov ax,[bx+2]
    inc word ptr[bx+0]
; =========================================================
    ; Wait for a key press before exiting.
    mov ah,0     
    int 16h
    int 20h
end start

eschew obfuscation

xxxx

thank you that was really helpful