The MASM Forum

Miscellaneous => 16 bit DOS Programming => Topic started by: turboscrew on December 13, 2013, 04:37:37 PM

Title: 16-bit MASM blues...
Post by: turboscrew on December 13, 2013, 04:37:37 PM
Now that I stumbled into 16-bit MASM-stuff: I remember why I never learned
x86 assembly so well...

The main headaches were:

My questions are:

That stuff is still very vaguely explained in the MASM manuals ("Programmer's Guide" and "Reference").

I guess when the command prompt starts the program, the CS is set to the program's code segment, but what's in the other segment registers?
Title: Re: 16-bit MASM blues...
Post by: dedndave on December 13, 2013, 08:03:50 PM
the MASM reference manual assumes that you are familiar with assembly language
the purpose of the manual is to provide syntax reference, not to teach assembly language

Quote
Is there something - even in principle - that starts something that END ends? If, then what?

yes - the program source text
text that appears after the END directive is ignored by the assembler
the END directive has an optional argument that is required for programs, but not for modules
that argument allows the programmer to specify the program entry point

Quote
SEGMENT: Does that define physical or logical segment? Looks like physical, because it doesn't take any indications of which kind of segment?

i guess i would say that a segment is a logical reference to a physical memory region   :biggrin:
as far as the assembler is concerned, it's logical (assembly-time)
when the program is executed, the operating system maps it to a physical/virtual area of memory (run-time)
16-bit DOS programs ran on systems with 1 MB addressable memory
a segment was actually a physical region in memory
32-bit/64-bit windows programs run on systems that address much more memory
segments are mapped to virtual pages or groups of pages of memory

simply put, the assembler uses segments to handle various memory attributes,
and as a reference for generating numeric addresses

Quote
The type (program/data/BSS) seems to be defined only by its use - that is: which segment register is set to point to it?

that's a fair observation under 16-bit DOS
although, to assemble executable instructions, it must be a CODE type segment

under 32-bit windows, segments map to sections of memory that have specific security attributes
various sections may allow or dis-allow reads, writes, or code execution
and - different privilege levels may have different access rights
for example, user-mode programs have ring-3 access (refer to the intel manuals)

Quote
.CODE and .DATA are logical segment start markers?

.CONST, .DATA, .DATA?, .CODE, and .STACK are aliases or shortcuts, intended to save typing
in "old style" syntax, segments are "opened" with a SEGMENT directive and "closed" with an ENDS directive
the programmer may provide name, type, combine, class, and a couple other attributes to a segment
segments may not be nested
masm provides shortcuts to open a limited set of standardized program segments
when the shortcuts are used, opening one segment automatically closes any previously opened segment

Quote
The linker may consolidate them to the same (unseen, internal) segments depending on the type?

as mentioned, segments have a "combine" attribute that tells the linker how they may be combined
furthermore, segments may be assigned to "groups"
in which case, the programmer may reference a group of segments and the linker will make them contiguous

Quote
The next .data continues where the last .data left off?

yes

Quote
What it is that ASSUME DS:@data does (in the assembler's point of view)?

the ASSUME directive has many uses, actually
but, when used for segment registers, it tells the assembler which program segment is pointed to by a specific register
a programmer may load a value into a segment register by use of a few different instructions
in some cases, it may be loaded from a variable
the assember cannot know what the value is at assemble-time

the specific directive "ASSUME DS:@data" is used to tell the assembler that the DS register points to DGROUP
DGROUP is a group that includes constant, initialized data, and uninitialized code sections
at least, that's the behaviour in the most commonly used memory models
for 32-bit code - all segments are in the same 4 GB addressable space (flat model)
but, in 16-bit DOS world, there are numerous models - the most common are TINY and SMALL
you can look at the reference material (or google) for descriptions of MEDIUM, COMPACT, LARGE, HUGE models

Quote
What is procedure block (from the assembler's point of view)? What are they used for?

simple answer, PROC = subroutine   :P
it's an individual block of code
not all PROC's are subroutines, because the main program code may be assembled as a PROC

Quote
I guess when the command prompt starts the program, the CS is set to the program's code segment, but what's in the other segment registers?

.EXE program headers have values that tell the operating system how to assign initial values to most segment registers (code, data, stack)
operation varies between DOS and windows
under win32, you can pretty much ignore segment registers
a "flat" memory model is used, and all segments essentially point to the same 4 GB of memory

16-bit .COM programs have all code, data, and stack within a single 64 KB segment (CS = DS = ES = SS)
although, you are allowed to access memory outside that segment at run-time
Title: Re: 16-bit MASM blues...
Post by: turboscrew on December 14, 2013, 07:23:34 AM
Well, I'm semi-familiar with x86 assembly and more familiar with PDP-11, 6502, 6800, 6809, 68000, PowerPC, 8085, TMS32C6000-series, and some other processor's assembly.

Quote
"Is there something - even in principle - that starts something that END ends? If, then what?"

yes - the program source text
So from my point of view - no.


Quote
SEGMENT: Does that define physical or logical segment? Looks like physical, because it doesn't take any indications of which kind of segment?

i guess i would say that a segment is a logical reference to a physical memory region   :biggrin:
as far as the assembler is concerned, it's logical (assembly-time)
when the program is executed, the operating system maps it to a physical/virtual area of memory (run-time)
16-bit DOS programs ran on systems with 1 MB addressable memory
a segment was actually a physical region in memory
32-bit/64-bit windows programs run on systems that address much more memory
segments are mapped to virtual pages or groups of pages of memory

simply put, the assembler uses segments to handle various memory attributes,
and as a reference for generating numeric addresses


The type (program/data/BSS) seems to be defined only by its use - that is: which segment register is set to point to it?

that's a fair observation under 16-bit DOS
although, to assemble executable instructions, it must be a CODE type segment

under 32-bit windows, segments map to sections of memory that have specific security attributes
various sections may allow or dis-allow reads, writes, or code execution
and - different privilege levels may have different access rights
for example, user-mode programs have ring-3 access (refer to the intel manuals)

I'd think that physical segment is something you configure in the MMU segment descriptor. Logical segments are rather kind of link-units,
like the segments or sections used with old 8-bit processors.
Title: Re: 16-bit MASM blues...
Post by: jj2007 on December 14, 2013, 11:18:41 AM
"Is there something - even in principle - that starts something that END ends? If, then what?"
Technically speaking, start: starts something that end ends:

include \masm32\include\masm32rt.inc  ; everything you need - read this file!

.code
AppName   db "Masm32:", 0

start:
   MsgBox 0, "Hello World", addr AppName, MB_OK
   exit

end start


This is how you tell the assembler & linker where you want to start your program. Note you can use turbo: .... end turbo if you prefer ;-)

Quote
I'd think that physical segment is something you configure in the MMU segment descriptor. Logical segments are rather kind of link-units, like the segments or sections used with old 8-bit processors.
Wiki has it all (http://en.wikipedia.org/wiki/Memory_management_unit#IA-32_.2F_x86). Or google tlb virtual memory
Title: Re: 16-bit MASM blues...
Post by: turboscrew on December 27, 2013, 06:59:30 PM
The SEGMET - ENDS pair is still a bit blurred, but maybe still another go with the socumentation...

The PROC - ENDP still puzzles me. In most assembly languages a label and RET is enough.
What does MASM use PROC for?
 
Title: Re: 16-bit MASM blues...
Post by: jj2007 on December 27, 2013, 07:13:00 PM
What does MASM use PROC for?

Go here (http://masm32.com/board/index.php?action=search;advanced;search=) and search for prologue epilogue macro
Same here (http://www.masmforum.com/board/index.php?action=search;advanced) - read specifically this thread (http://www.masmforum.com/board/index.php?topic=18794.0).
Then come back next year for questions ;)
Title: Re: 16-bit MASM blues...
Post by: turboscrew on December 27, 2013, 09:42:04 PM
Does PROC - ENDP generate a (C) function prologue/epilogue for "outside" calls ?
Does it create a new stack frame and save some registers (add stuff to the code)?
Or does it add some info to the procedure name symbol for the linker?

Another question: does the need of "verification" ever go away?
Title: Re: 16-bit MASM blues...
Post by: Gunther on December 27, 2013, 10:08:57 PM
Hi turboscrew,

Does PROC - ENDP generate a (C) function prologue/epilogue for "outside" calls ?

No, not automatically. You've to do that by hand or with appropriate macros.

Does it create a new stack frame and save some registers (add stuff to the code)?

Same answer, see above. By the way, The PROC ENDP is a bit red band. A procedure is a simple label inside the source code. There are other assemblers (NASM, YASM) which don't need PROC ENDP. If you're interested, you should give them a try.

Gunther
Title: Re: 16-bit MASM blues...
Post by: jj2007 on December 27, 2013, 11:32:25 PM
The PROC ENDP is a bit red band. A procedure is a simple label inside the source code. There are other assemblers (NASM, YASM) which don't need PROC ENDP.

So how do they decide how to interpret "ret"?

include \masm32\include\masm32rt.inc
.code

MyProc proc uses esi arg1
LOCAL v1, rc:RECT
  print str$(arg1)
  ret      ; = pop esi, leave, retn 4
MyProc endp

SomeLabel:
  MsgBox 0, "Hello World", "Title", MB_OK
  ret      ; =?

start:
   invoke MyProc, 123
   call SomeLabel
   exit
end start
Title: Re: 16-bit MASM blues...
Post by: turboscrew on December 28, 2013, 12:44:33 AM

...procedure is a simple label inside the source code. There are other assemblers (NASM, YASM) which don't need PROC ENDP. If you're interested, you should give them a try.

Gunther

That's why I've been wondering.
Any other assembly that I know (I don't know Intel-assemblers too well) doesn't have such.
Not even GAS for x86 (AT&T syntax).
With MASM-"family" assemblers that seems to be necessary.

Title: Re: 16-bit MASM blues...
Post by: Gunther on December 28, 2013, 01:30:41 AM
Jochen,

So how do they decide how to interpret "ret"?


What is the result of RET? Should I explain for you the content of the processor manual? You're joking, don't you?

Here's an example:
Code: [Select]
SECTION .data

msg db "Hello, world!",0xa ;
len equ     $ - msg

SECTION .text
global main

main:
        mov     eax,4 ; write system call
        mov     ebx,1           ; file (stdou)
        mov     ecx,msg         ; string
        mov     edx,len         ; strlen
int     0x80 ; call kernel

mov eax,1 ; exit system call
        mov     ebx,0     
        int     0x80 ; call kernel

That will work under Linux and BSD. Main is a simple label, what else?

Gunther
Title: Re: 16-bit MASM blues...
Post by: dedndave on December 28, 2013, 01:48:53 AM
if a PROC has parameters, USES, or LOCAL's, Masm will generate an epilogue whenever it sees RET
it must be a "vanilla" RET - not RETN
you can, of course, disable the epilogue with OPTION
Title: Re: 16-bit MASM blues...
Post by: jj2007 on December 28, 2013, 04:15:03 AM
You're joking, don't you?

Gunther,

No, I am not joking. Just try to build my example with an assembler that creates automatically a stack frame and doesn't need endp. Dave gave you already a hint.

Jochen
Title: Re: 16-bit MASM blues...
Post by: Gunther on December 28, 2013, 05:20:27 AM
Jochen,

No, I am not joking. Just try to build my example with an assembler that creates automatically a stack frame and doesn't need endp. Dave gave you already a hint.

Neither NASM still YASM create automatically a stack frame. My point was, that a procedure is a label inside the source code, not more, not less. All these other stuff (LOCALs, USES, INVOKE etc.) is very assembler specific (MASM, JWASM) and isn't really necessary. It is comfortable, no doubt, but one can live without that.

The target direction of this thread was the question about this stuff. The PROC, ENDP is necessary for MASM type assemblers, but not for others. It is not so easy for starters or coders from another platform to look behind the scenes and separate the important from the unimportant. I hope that's clear enough. No offending.

Gunther
Title: Re: 16-bit MASM blues...
Post by: jj2007 on December 28, 2013, 06:13:56 AM
Neither NASM still YASM create automatically a stack frame. My point was, that a procedure is a label inside the source code, not more, not less.

For Masm/JWasm, a procedure is much more than just a label. But of course, real menTM can live without invoke, macros, locals, stack frames and other fashionable gadgets ;-)

Again, no offense intended. My point was that the endp delimits the scope of a procedure, and that ret has a different meaning above and below the endp.
Title: Re: 16-bit MASM blues...
Post by: Gunther on December 28, 2013, 06:54:55 AM
Jochen,

My point was that the endp delimits the scope of a procedure, and that ret has a different meaning above and below the endp.

that's clear and it has to do with MASM/JWASM gadgets. But turboscrew has some difficulties with that stuff. That was my point.

Gunther
Title: Re: 16-bit MASM blues...
Post by: turboscrew on December 28, 2013, 07:24:11 AM
No Linux here, since this "department" is about 16-bit assembly - architecture that Linux won't run on.

Also, I can use, say, AT&T, but that doesn't help understanding the "meaning" of PROC (and 16-bit Intel assembly).

Anyway, since RET has different meaning inside and outside of procedure block tells me that procedure block has some (essential) role in 16-bit x86 assembly, but what?

Title: Re: 16-bit MASM blues...
Post by: FORTRANS on December 28, 2013, 08:45:27 AM
Hi,

   As has been mentioned, PROC and ENDP can cause some actions
to occur.  However at its most simple usage, it has little effect.  See
the code generated for the following two routines.

Code: [Select]
      13 0000  50 CRLF:   PUSH    AX      ; Save affected registers
      14 0001  52         PUSH    DX
      15
      16 0002  B2 0D         MOV     DL,13   ; CR
      17         SCALL CONOUT
      18 0004  B4 02                 1 MOV AH,DOSF_CONOUT
      19 0006  CD 21                 1 INT 21H
      20 0008  B2 0A         MOV     DL,10   ; LF
      21         SCALL CONOUT
      22 000A  B4 02                 1 MOV AH,DOSF_CONOUT
      23 000C  CD 21                 1 INT 21H
      24
      25 000E  5A         POP     DX      ; Restore registers
      26 000F  58         POP     AX
      27
      28 0010  C3         RET
      29
      30 ; - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - -
      31 0011 NewLine PROC
      32
      33 0011  50         PUSH    AX      ; Save affected registers
      34 0012  52         PUSH    DX
      35
      36 0013  B2 0D         MOV     DL,13   ; CR
      37         SCALL CONOUT
      38 0015  B4 02                 1 MOV AH,DOSF_CONOUT
      39 0017  CD 21                 1 INT 21H
      40 0019  B2 0A         MOV     DL,10   ; LF
      41         SCALL CONOUT
      42 001B  B4 02                 1 MOV AH,DOSF_CONOUT
      43 001D  CD 21                 1 INT 21H
      44
      45 001F  5A         POP     DX      ; Restore registers
      46 0020  58         POP     AX
      47
      48 0021  C3         RET
      49
      50 0022 NewLine ENDP
      51 ; - - - - - - - - - - - - - - - - - - -

   Here there is no difference in the code generated when using
PROC/ENDP or a simple label.  So if you do not apply options,
and use it correctly, PROC/ENDP acts as a visual delimiter for
your routine.

Regards,

Steve N.
Title: Re: 16-bit MASM blues...
Post by: Gunther on December 28, 2013, 11:40:49 AM
Hi  turboscrew,

No Linux here, since this "department" is about 16-bit assembly - architecture that Linux won't run on.

take care, Linux can run on 16 bit machines. (https://en.wikipedia.org/wiki/Embeddable_Linux_Kernel_Subset) I've done that a few years ago on an embedded system.

But that's not my point. I've attached the archive hello.zip. It contains 4 files. HELLOM.ASM is the MASM/JWASM/TASM source for a simple hello world COM program. HELLON.ASM is the YASM/NASM equivalent. The functionality is the same and the differences are not so hard. The code should be self explanatory and is good commented. I hope that helps.

Gunther
Title: Re: 16-bit MASM blues...
Post by: turboscrew on December 28, 2013, 08:08:30 PM
(ELKS is a subset, not full Linux. There is also uClinux, but it's not considered full linux either.)

Well, it still hasn't sunk into my hard head what PROC really is (or procedure block).
The only "stand up" effect I have found out this far is that the assembler takes the labels
within a procedure block as locals.

Title: Re: 16-bit MASM blues...
Post by: dedndave on December 28, 2013, 10:10:17 PM
a PROC is typically a subroutine - it's that simple
whenever you think of CALL, think PROC   :P

if you come from C world
PROC = {
ENDP = }
Title: Re: 16-bit MASM blues...
Post by: FORTRANS on December 29, 2013, 12:29:01 AM
Hi,

   As Dave says, PROC and ENDP (help to) define a subroutine
or procedure.  In my earlier example, it did not do anything
except provide "labels" for the start and end of the routine.
In this example the PROC statement will have an option applied
to it, and that will affect how the assembler treats the code
within that PROCedure.

Code: [Select]
      13 ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      14 0000 CRLF    PROC    FAR
      15 0000  50         PUSH    AX      ; Save affected registers
      16 0001  52         PUSH    DX
      17
      18 0002  B2 0D         MOV     DL,13   ; CR
      19         SCALL CONOUT
      20 0004  B4 02                 1 MOV AH,DOSF_CONOUT
      21 0006  CD 21                 1 INT 21H
      22 0008  B2 0A         MOV     DL,10   ; LF
      23         SCALL CONOUT
      24 000A  B4 02                 1 MOV AH,DOSF_CONOUT
      25 000C  CD 21                 1 INT 21H
      26
      27 000E  5A         POP     DX      ; Restore registers
      28 000F  58         POP     AX
      29
      30 0010  CB         RET
      31
      32 0011 CRLF    ENDP
      33 ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      34 0011 NewLine PROC    NEAR
      35
      36 0011  50         PUSH    AX      ; Save affected registers
      37 0012  52         PUSH    DX
      38
      39 0013  B2 0D         MOV     DL,13   ; CR
      40         SCALL CONOUT
      41 0015  B4 02                 1 MOV AH,DOSF_CONOUT
      42 0017  CD 21                 1 INT 21H
      43 0019  B2 0A         MOV     DL,10   ; LF
      44         SCALL CONOUT
      45 001B  B4 02                 1 MOV AH,DOSF_CONOUT
      46 001D  CD 21                 1 INT 21H
      47
      48 001F  5A         POP     DX      ; Restore registers
      49 0020  58         POP     AX
      50
      51 0021  C3         RET
      52
      53 0022 NewLine ENDP
      54 ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

   The assembler now knows that the RETurn instructions are of
different types.  And makes the appropriate change to a near or
far return.

   So the PROC/ENDP tells the MASM assembler what characteristics
should be applied to a block of code.  See the listing of the variables
to see if anything happened.

Code: [Select]
                N a m e          Type Value Attr

CRLF . . . . . . . . . . . . . .  F PROC 0000 CODE Length = 0011

NEWLINE  . . . . . . . . . . . .  N PROC 0011 CODE Length = 0011

   You can apply an option to the PROC directive and make a
listing to see what changes.  In my earlier example, I showed
that you can avoid using the PROC and ENDP directives if you
want.

Regards,

Steve N.
Title: Re: 16-bit MASM blues...
Post by: turboscrew on December 29, 2013, 06:13:09 AM
So, did I understand it right:

PROC - ENDP as such do nothing (except with options, like NEAR or FAR), but really define a scope where other
(more or less procedure-oriented) options, directives and the like apply?

And it looks like ASSUME DS:segment really tells the assembler what kind of code to emit for data accesses: like far + segment or near.
Title: Re: 16-bit MASM blues...
Post by: dedndave on December 29, 2013, 07:34:49 AM
there are a few other qualifiers that may be added to the PROC line, as well

for example, USES preserves and restores registers for you
Code: [Select]
MyFunc PROC USES BX SI DI arg1:WORD

    ret

MyFunc ENDP

also, PROC labels are PUBLIC, by nature, but can be made PRIVATE
and - the calling convention that you specify at the beginning of the program may be overridden
refer to the Masm Programmers Guide - available in PDF, let me know if you need a link
Title: Re: 16-bit MASM blues...
Post by: turboscrew on December 29, 2013, 09:18:47 AM
I saw a link to the 2004-2012 archive site, but I haven't yet registered there.

But roughly, the PROC - ENDP defines a scope?
Title: Re: 16-bit MASM blues...
Post by: dedndave on December 29, 2013, 09:43:25 AM
sure - that refers to the scope of (local) variables on the stack for the instance of the call
when the function returns, the variables are lost - thus, they have limited scope
Title: Re: 16-bit MASM blues...
Post by: Gunther on December 29, 2013, 10:30:51 AM
turboscrew,

But roughly, the PROC - ENDP defines a scope?

Yes. These are special directives (sometimes called pseudo operations, pseudo directives and the like). You should have a look into that source, (http://www.oopweb.com/Assembly/Documents/ArtOfAssembly/Volume/toc.html) especially chapter 8.

Gunther
Title: Re: 16-bit MASM blues...
Post by: MichaelW on December 29, 2013, 06:37:33 PM
An arbitrarily complex procedure and invoke, done in 32-bit code for convenience.
Code: [Select]
;========================================================================================
include \masm32\include\masm32rt.inc
.686
;========================================================================================
.data
    dd1   dd    12345678h
    r8    REAL8 1234.56789
    dq1   dq    1234567812345678h
    rect  RECT  <1,2,3,4>
.code
;========================================================================================
proc1 proc uses gs ebx edi esi param1:DWORD, param2:REAL8, param3:QWORD, param4:RECT
    LOCAL local1:DWORD
    LOCAL local2:REAL8
    LOCAL local3:QWORD
    LOCAL local4:RECT
    LOCAL local5[4]:DWORD
    push  param1
    pop   local1
    fld   param2
    fstp  local2
    fild  param3
    fistp local3
    push param4.left
    pop  local4.left
    push param4.top
    pop  local4.top
    push param4.right
    pop  local4.right
    push param4.bottom
    pop  local4.bottom
    nop
    printf("%Xh\n",local1)
    printf("%f\n",local2)
    printf("%I64Xh\n",local3)
    printf("%d\t%d\t%d\t%d\n\n",local4.left,local4.top,local4.right,local4.bottom)
    nop
    mov eax, param1
    mov local5, eax
    mov local5[4], eax
    mov local5[8], eax
    mov local5[12], eax
    xor eax, eax
    add eax, local5
    add eax, local5[4]
    add eax, local5[8]
    add eax, local5[12]
    ret
proc1 endp
;========================================================================================
start:
;========================================================================================
    mov eax, DWORD PTR dq1
    mov edx, DWORD PTR dq1+4
    invoke proc1, dd1, r8, edx::eax, rect
    mov ecx, 4
    cdq
    div ecx
    printf("%Xh\n\n",eax)
    inkey
    exit
;========================================================================================
end start
Code: [Select]
12345678h
1234.567890
1234567812345678h
1       2       3       4

12345678h
Code: [Select]
00401000   $ 55             PUSH EBP
00401001   . 8BEC           MOV EBP,ESP
00401003   . 83C4 CC        ADD ESP,-34
00401006   . 0FA8           PUSH GS
00401008   . 53             PUSH EBX
00401009   . 57             PUSH EDI
0040100A   . 56             PUSH ESI
0040100B   . FF75 08        PUSH DWORD PTR SS:[EBP+8]
0040100E   . 8F45 FC        POP DWORD PTR SS:[EBP-4]
00401011   . DD45 0C        FLD QWORD PTR SS:[EBP+C]
00401014   . DD5D F4        FSTP QWORD PTR SS:[EBP-C]
00401017   . DF6D 14        FILD QWORD PTR SS:[EBP+14]
0040101A   . DF7D EC        FISTP QWORD PTR SS:[EBP-14]
0040101D   . FF75 1C        PUSH DWORD PTR SS:[EBP+1C]
00401020   . 8F45 DC        POP DWORD PTR SS:[EBP-24]
00401023   . FF75 20        PUSH DWORD PTR SS:[EBP+20]
00401026   . 8F45 E0        POP DWORD PTR SS:[EBP-20]
00401029   . FF75 24        PUSH DWORD PTR SS:[EBP+24]
0040102C   . 8F45 E4        POP DWORD PTR SS:[EBP-1C]
0040102F   . FF75 28        PUSH DWORD PTR SS:[EBP+28]
00401032   . 8F45 E8        POP DWORD PTR SS:[EBP-18]
00401035   . 90             NOP
00401036   . FF75 FC        PUSH DWORD PTR SS:[EBP-4]                ; /<%X>
00401039   . 68 24304000    PUSH test.00403024                       ; |format = "%Xh
"
0040103E   . FF15 20204000  CALL DWORD PTR DS:[<&msvcrt.printf>]     ; \printf
00401044   . 83C4 08        ADD ESP,8
00401047   . FF75 F8        PUSH DWORD PTR SS:[EBP-8]
0040104A   . FF75 F4        PUSH DWORD PTR SS:[EBP-C]                ; /<%f>
0040104D   . 68 2C304000    PUSH test.0040302C                       ; |format = "%f
"
00401052   . FF15 20204000  CALL DWORD PTR DS:[<&msvcrt.printf>]     ; \printf
00401058   . 83C4 0C        ADD ESP,0C
0040105B   . FF75 F0        PUSH DWORD PTR SS:[EBP-10]
0040105E   . FF75 EC        PUSH DWORD PTR SS:[EBP-14]               ; |
00401061   . 68 34304000    PUSH test.00403034                       ; |format = "%I64Xh
"
00401066   . FF15 20204000  CALL DWORD PTR DS:[<&msvcrt.printf>]     ; \printf
0040106C   . 83C4 0C        ADD ESP,0C
0040106F   . FF75 E8        PUSH DWORD PTR SS:[EBP-18]               ; /<%d>
00401072   . FF75 E4        PUSH DWORD PTR SS:[EBP-1C]               ; |<%d>
00401075   . FF75 E0        PUSH DWORD PTR SS:[EBP-20]               ; |<%d>
00401078   . FF75 DC        PUSH DWORD PTR SS:[EBP-24]               ; |<%d>
0040107B   . 68 40304000    PUSH test.00403040                       ; |format = "%d %d %d %d

"
00401080   . FF15 20204000  CALL DWORD PTR DS:[<&msvcrt.printf>]     ; \printf
00401086   . 83C4 14        ADD ESP,14
00401089   . 90             NOP
0040108A   . 8B45 08        MOV EAX,DWORD PTR SS:[EBP+8]
0040108D   . 8945 CC        MOV DWORD PTR SS:[EBP-34],EAX
00401090   . 8945 D0        MOV DWORD PTR SS:[EBP-30],EAX
00401093   . 8945 D4        MOV DWORD PTR SS:[EBP-2C],EAX
00401096   . 8945 D8        MOV DWORD PTR SS:[EBP-28],EAX
00401099   . 33C0           XOR EAX,EAX
0040109B   . 0345 CC        ADD EAX,DWORD PTR SS:[EBP-34]
0040109E   . 0345 D0        ADD EAX,DWORD PTR SS:[EBP-30]
004010A1   . 0345 D4        ADD EAX,DWORD PTR SS:[EBP-2C]
004010A4   . 0345 D8        ADD EAX,DWORD PTR SS:[EBP-28]
004010A7   . 5E             POP ESI
004010A8   . 5F             POP EDI
004010A9   . 5B             POP EBX
004010AA   . 0FA9           POP GS                                   ;  Modification of segment register
004010AC   . C9             LEAVE
004010AD   . C2 2400        RETN 24
004010B0 >/$ A1 0C304000    MOV EAX,DWORD PTR DS:[40300C]
004010B5  |. 8B15 10304000  MOV EDX,DWORD PTR DS:[403010]
004010BB  |. FF35 20304000  PUSH DWORD PTR DS:[403020]
004010C1  |. FF35 1C304000  PUSH DWORD PTR DS:[40301C]
004010C7  |. FF35 18304000  PUSH DWORD PTR DS:[403018]
004010CD  |. FF35 14304000  PUSH DWORD PTR DS:[403014]
004010D3  |. 52             PUSH EDX
004010D4  |. 50             PUSH EAX
004010D5  |. FF35 08304000  PUSH DWORD PTR DS:[403008]
004010DB  |. FF35 04304000  PUSH DWORD PTR DS:[403004]
004010E1  |. FF35 00304000  PUSH DWORD PTR DS:[403000]
004010E7  |. E8 14FFFFFF    CALL test.00401000
004010EC  |. B9 04000000    MOV ECX,4
004010F1  |. 99             CDQ
004010F2  |. F7F1           DIV ECX

Title: Re: 16-bit MASM blues...
Post by: FORTRANS on December 30, 2013, 01:09:00 AM
And it looks like ASSUME DS:segment really tells the assembler what kind of code to emit for data accesses: like far + segment or near.

Hi,

   Right.  ASSUME tells the assembler what to expect it to use
when accessing a symbol (label).  See the following example.

Code: [Select]
       7 ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       8 0000 DATASEG SEGMENT
       9 0000  41 6D 70 68 69 62 69 FROG    DB      'Amphibian$'
      10       61 6E 24
      11 000A DATASEG ENDS
      12 ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      13 0000 OTHERSG SEGMENT
      14 0000  52 65 70 74 69 6C 65 GILA    DB      'Reptile'
      15 0007 OTHERSG ENDS
      16 ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      17 0000 CODE    SEGMENT PUBLIC 'CODE'
      18         ASSUME  CS:CODE
      19
      20 0000 Start   PROC
      21 0000  B8 ---- R         MOV     AX,SEG DATASEG
      22 0003  8E D8         MOV     DS,AX
      23 0005  B8 ---- R         MOV     AX,SEG OTHERSG
      24 0008  8E C0         MOV     ES,AX
      25         ASSUME  CS:CODE, DS:DATASEG, ES:OTHERSG
      26 000A  A0 0000 R         MOV     AL,[FROG]       ; Put 'A' into AL.
      27 000D  26: 8A 1E 0000 R         MOV     BL,[GILA]       ; Put 'R' into BL.

   Note that 26H is the ES segment override prefix.  (You may
also note that AL is an accumulator register, and has a special
form of the MOV instruction.)

Regards,

Steve N.
Title: Re: 16-bit MASM blues...
Post by: turboscrew on December 30, 2013, 08:44:07 AM
Truckload of thanks, guys.
I guess I finally got a good grip of those forever-bothered the things that have bothered me "forever".