News:

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

Problem with Alingment and Pointers in Masm

Started by Zest, October 15, 2006, 09:49:54 AM

Previous topic - Next topic

Zest

Hi,
This is a snippet of code:

.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib


BOOKS STRUCT
  mTitle    db 20 dup(0)
  mAuthor   db 20 dup(0)
  mPrice    dw ?                 
BOOKS ENDS     


.data

book1 BOOKS <'assembly', 'Ben' ,126>
iCaption db "C++ version 5",0

.data?


hInstance dd ?
CommandLine dd ?

.code
main:     
   
    invoke GetModuleHandle, NULL
    mov hInstance,eax
    invoke GetCommandLine
    mov CommandLine,eax

    mov edx, offset book1
    assume edx: PTR BOOKS

    pushfd                   ; store the flags, since we gonna use cld
    mov ecx, sizeof iCaption ; number of bytes to copy
    lea esi, iCaption        ; address of source
    lea edi,[edx].mTitle     ; address of the destination
    cld                      ; increase edi/esi up
    rep movsb                ; copy byte at es:si -> es:di, and increae pointer by 1
    popfd                    ; pop the flags

    invoke ExitProcess,eax
end main


Now I have some questions about this snippet of code:

I have used the align directive before iCaption


ALIGN 4
iCaption db "C++ version 5",0


It made the data be arranged in 16 bit by 16 bit order.
The DWORD means 32 bits.
So, movsd tries to transfer data 32 bit by 32 bit.

The problem is that I don't know how to calculate the correct number which should be put in ECX.

I hope someone help me and let me know what changes should be done on this instruction:

mov ecx, sizeof iCaption

Also I wanted to use ALIGN 8 which should arrange data in 256 orders.

But the assembler complained that:

Quote-------------------Configuration: RES - Debug--------------------
Assembling: ..\RES.asm
..\RES.asm(39) : error A2189: invalid combination with segment alignment : 8
RES.obj - 1 error(s), 0 warning(s)


So now I have to change the segment alignment to PAGE to overcome this problem.
because the predefined alignment for .DATA segment is PARA which is in fact PARAGRAPH or 16 bits.

How can I change this predefined alignment in .DATA segment?

Looking through segment definition I noticed that we have something
which is called .FARDATA

What's the use of this segment?
Is there anybody who can mention some usabilities of this segment?


The other question is about these instructions:

    mov edx, offset book1
    assume edx: PTR BOOKS


As far as I know assume directive has this format :

QuoteASSUME dataregister:type
[[distance]] PTR type

So a valid instruction is :

ASSUME eax:PTR BYTE
or
ASSUME eax:PTR WORD
or
ASSUME eax:PTR DWORD



So after PTR we need a type to be used while here the name of the original structure is used.
It's somehow ambiguous for me.
Is tehre anybody who can explain?
Maybe it's a very special and individual instruction made just for structures.

The last question is about pointers in assembly.
One way to introduce them in assmbly is like this:


byteptr         typedef near ptr byte

So imagine you have an array of cracters which is named :
'MyString'

The to make a pointer to this array you can use this instruction:

bytestr      byteptr   MyString


Now the bytestr is pointer to 'MyString'

The other way which was used in old days would be like this:


les     bx, p           ;Load p into ES:BX
mov     es:[bx], al     ;Store away AL


In fact, 'LES' was the special instruction for making pointers in old days
in 16 bit assembly .
Is there any new equivalent for 32 bit assembly?

I want to know if there is any other way to introduce pointers in assembly.

Here is a part of AOA which introduce a new type of data which is just used for pointers:

Quote
The df/fword statement's main utility is declaring 48 bit pointers for use in 32 bit protected mode on the 80386 and later. Although you could use this directive to create an arbitrary six byte variable, there are better directives for doing that. You should only use this directive for 48 bit far pointers on the 80386.

In fact,I couldn't find any example of using this kind of pointers.
Is it possible to show me how you use FWORD to declare 48 bit pointers?

Sorry,if I made so many questions.
In fact ,I searched through the whole AOA book and couldn't find any answer to these questions.

Then I asked them here as I know there are some veterans here who have gained a lot of experience.

Thanks in advance.
Best Regards,
Zest.









hutch--

Hi Zest,

Welcome on board. Set your processor model to .486 or higher to use alignment above 4.

You can routinely use "align 16" once you enable a higher processor model.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

MichaelW

Hi Zest,

ECX specifies the number of times the string instruction will be repeated so, for example, to move 16 bytes using MOVSD you would set ECX to 4.

A paragraph is 16 bytes, not 16 bits.

If you use an ASSUME dataregister:type statement, you should normally remove the assumption when you are finished using it. There is also another method of accessing structure members through a register that does not require an ASSUME statement.

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
      rc RECT <>
    .code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    mov rc.left, 1
    mov rc.top, 2
    mov rc.right, 3
    mov rc.bottom, 4

    mov ebx, OFFSET rc
   
    ASSUME ebx:PTR RECT
    print ustr$([ebx].left),13,10
    print ustr$([ebx].top),13,10
    print ustr$([ebx].right),13,10
    print ustr$([ebx].bottom),13,10
    ASSUME ebx:nothing

    ; Alternative method with no ASSUME.

    print ustr$([ebx].RECT.left),13,10
    print ustr$([ebx].RECT.top),13,10
    print ustr$([ebx].RECT.right),13,10
    print ustr$([ebx].RECT.bottom),13,10

    inkey "Press any key to exit..."
    exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start


FWORD would typically be used in code that sets up protected mode (something that you would not be doing in a Windows application). Examples would be:

; Load descriptor table registers
lidt FWORD PTR idt_descriptor
lgdt FWORD PTR gdt_descriptor

IIRC it can also be used in one possible method of doing an inter-segment jump, immediately after PM is entered, to flush the instruction queue and load CS with a valid selector.
eschew obfuscation

Zest

Dear Michael,
Hello,
Thanks for your fair reply.
I got everything.
But I have some other questions:

First ,you didn't talk about this predefined section in assembly

.FARDATA

What's the use of it and when do you use this section?

Also let me know if there is a way to FORCE the LINKER to make a relocation section
for the exe files while it's linking.
I know this section is just for DLL files,but I want to have this section with my EXE file.
Is there any way to do so?

There is an option with microsoft linker.

/BASE:{address|@filename,key}

Does it change the base image numner of the exe file?
How can I use this option?

The last question is about inter-segment jump.
Do you know where I can read about this method ?
Did you study it in a book or an article?
I need to see some codes which use this method.

Thanks in advance.
Best Regards,
Zest.

tenkey

It seems from my VS6 version of MSDN that you can force the creation of a relocation table by using the linker switch

/FIXED:NO
A programming language is low level when its programs require attention to the irrelevant.
Alan Perlis, Epigram #8

Zest

Thanks tenkey.
This option works for me.
:wink
Regards,
Zest.

MichaelW

For the DOS memory models .FARDATA would start a far data segment for initialized data, but I can't see how the concept of far has any meaning in a flat address space. Testing just now it looks like MASM combines a .FARDATA segment with the .DATA segment, and a .FARDATA? segment with the .DATA? segment.

Most of what I know about PM I got out of various books, in combination with a lot of testing, and a long series of code, assemble, test, and reset (after it hangs) cycles.

There are multiple PM tutorials available here. I have not examined all of the tutorials, but PM-9-94.ZIP is very good, with several extenders and examples, all done in MASM, and several documents.
eschew obfuscation

Zest

Hi ,
Thanks for the reply.
I'm going to read some of these articles.
I hope most of my questions are answered there.

Regards,
Zest.