News:

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

Suggestion with MSVCRT code.

Started by hutch--, June 06, 2005, 04:59:13 AM

Previous topic - Next topic

GregL

zooba,

Sorry, I'll stop posting the long code pieces. Point taken.


hutch--

Greg,

Thanks for doing this much work, I know it has been time consuming but we have ended up with not only some very usiful and reliable conversions but some very useful macros for writing other more powerful macros. I now have them added to the reference version of macros.asm.

By getting enough preprocessor code up and running, the capacity has something to offer the more experienced programmer who is interested in extending the precision and accuracy of assembler coding in efficient and time effective ways. A reliable body of preprocessor code also makes the lead time from entry to production with programmers learning assembler programming a lot shorter.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

GregL

Hutch,

You are welcome, I enjoy writing this stuff, and I am pleased you found it good enough to include in the MASM32 macros.


hutch--

Greg,

I just want to try this idea out on you. I have so far renamed the sscanf macros to get their names shorter as follows. I was interested in the idea of using EXITM <OFFSET retval> so that these macros could be used like functions and make them easier to use. Does this make sense to you ?


a2ub    PROTO pStr:PTR BYTE, pUb :PTR BYTE
a2sb    PROTO pStr:PTR BYTE, pSb :PTR SBYTE
h2ub    PROTO pStr:PTR BYTE, pUb :PTR BYTE
a2uw    PROTO pStr:PTR BYTE, pUw :PTR WORD
a2sw    PROTO pStr:PTR BYTE, pSw :PTR SWORD
h2uw    PROTO pStr:PTR BYTE, pUw :PTR WORD
a2ud    PROTO pStr:PTR BYTE, pUdw:PTR DWORD
a2sd    PROTO pStr:PTR BYTE, pSdw:PTR SDWORD
h2ud    PROTO pStr:PTR BYTE, pUdw:PTR DWORD
a2uq    PROTO pStr:PTR BYTE, pUqw:PTR QWORD
a2sq    PROTO pStr:PTR BYTE, pSqw:PTR QWORD
h2sq    PROTO pStr:PTR BYTE, pUqw:PTR QWORD
a2r4    PROTO pStr:PTR BYTE, pR4 :PTR REAL4
a2r8    PROTO pStr:PTR BYTE, pR8 :PTR REAL8
a2r10   PROTO pStr:PTR BYTE, pR10:PTR REAL10


PS: I like your avatar from the front cover of Aqualung, I have the CD on my workdesk.  :bg
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

GregL

Hutch,

Yes, it makes sense. The names were rather long. I converted one of the sscanf procedures to a macro, just to test the concept, but I never posted it, and I never got around to converting the rest. Looks good to me :U

I have fond memories of the time when the 'Aqualung' album came out. 
 

GregL

I removed unneeded 'tmp' variables from udword$, sdword$ and xdword$ in the sprintf macros posted above: http://www.masmforum.com/simple/index.php?topic=1851.msg17946#msg17946
 


Codewarp

Hutch -

Do I understand this thread right--you are putting together a complete msvcrt.dll in masm source code, with all api's and (hopefully) a faster implementation?  Does this include a multi-threaded version as well??  If so, there is a lot of speed to be had in the multi-threaded memory heap allocator, as long as you can avoid using locks and critical sections, in favor of lock-free methods.  The locks in msvcrt heap calls account for 60-80% of the time it spends (and 20% on memory management).  Lock-free methods can eliminate most of that overhead, tripling allocation performance.  Many applications often operate at "heap-bound" performance levels, and better allocator performance can directly show up in running client applications.

I have written and use a complete general purpose memory allocator that is 15 times faster than the msvcrt.dll, and plan to extend it, using lock-free methods, coupled with local dynamic per-thread memory pools.  It would be cool if your code supported installable heap management, so that I could make my methods available through the standard heap management calls.  My code for this is in C++, and likely to stay that way, but it can provide and access any conceivable interface from its own dll.

Also, I cannot seem to find any description of what parts of the msvcrt codebase are finished and which pieces are still wanting.  Such a description would make it a lot easier for those of us who would to add to this project, to be able to know what is needed and wanted at any given time.

hutch--

Codewarp,

In the latest service pack for masm32 there is a utility that creates both an include fle for the MSVCRT dll and a library as well. MSVCRT is a "known" dll so it can be reliably used from win95b upwards and that was its appeal. The function count is about 730 functions. It sounds like you have some good design there but rewriting a DLL the size of MSVCRT is a very large task.

One of our members recently did some benchmarks on different memory allocation strategies and using the low fragmentation heap there were some performance advantages using it but the results were interesting, the ancient GlobalAlloc() was the fastest on large allocations where HeapAlloc() was faster on repeated small allocations. The big loser was OLE string memory tha used to be fast on win9x but was definitely off the pace on later NT based OS versions.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

GregL

#98
Variable Argument Functions and Argument Promotion in C, and How it Applies to Calling C Run-Time Library Functions from MASM

Certain C Run-Time functions, such as 'printf' and 'scanf', will accept a variable number of arguments. Because there is no formal prototype for variable argument functions, 'default argument promotion' applies. For 'unsigned char', 'signed char', 'unsigned short' and  'signed short' arguments, the C compiler promotes the  arguments to either 'unsigned int' or 'signed int' before the variable argument function is called. Also, 'float' arguments are promoted to 'double' before the function is called.

Quote from: ANSI C StandardANSI 3.3.2.2: "If the expression that denotes the called function has a type that does not include a prototype, the integral promotions are performed on each argument and arguments that have type float are promoted to double. These are called the default argument promotions. If the number of arguments does not agree with the number of  parameters, the behavior is undefined."

So, in MASM, we must do the argument promotion ourselves, before calling a variable argument C function.  BYTE, SBYTE, WORD and SWORD arguments must be zero-extended or sign-extended to either a DWORD or SDWORD. A REAL4 must be converted to a REAL8 before calling a variable argument C function. A REAL10 must be converted to a REAL8 before calling a variable argument C function, this is explained in the following  MSDN excerpt.

Quote from: MSDNPrevious 16-bit versions of Microsoft C/C++ and Microsoft Visual C++ supported the long double,  80-bit precision data type. In Win32 programming, however, the long double data type maps to the  double, 64-bit precision data type. The Microsoft run-time library provides long double versions  of the math functions only for backward compatibility. The long double function prototypes are  identical to the prototypes for their double counterparts, except that the long double data type  replaces the double data type. The long double versions of these functions should not be used in  new code.

We can still use the REAL10 data type in MASM Win32 programming, but when calling a C Run-Time  function you must convert the REAL10 to a REAL8 before the call. I have heard the Intel C  compiler supports the REAL10 data type but we are using MSVCRT.DLL (Microsoft).

GregL

Passing Strings to C Run-Time Library Functions from MASM

If you pass a string that contains escape sequences ( \t \n \r)  to a C Run-Time Library function, like printf, from MASM, it doesn't work.

.586
.MODEL FLAT, stdcall
option casemap:none

include windows.inc

include kernel32.inc
include user32.inc
include masm32.inc
include msvcrt.inc

include c:\masm32\macros\macros.asm

includelib kernel32.lib
includelib user32.lib
includelib masm32.lib
includelib msvcrt.lib

.DATA

    count   DWORD 2
    String  BYTE  "\tThis is a string containing %d escape sequences\n", 0

.CODE

start:

    invoke crt_printf, ADDR String, count
   
    invoke ExitProcess, 0

end start


the output is:

\tThis is a string containing 2 escape sequences\n


The C compiler converts the escape sequences to their ASCII value before sending the string to the function. Here is an example.

C program:

#include <stdio.h>

int main(void)
{
    int count = 2;

    printf("\tThis is a string containing %d escape sequences\n", count);

    return 0;
}


Assembly listing of above C program:

; Listing generated by Microsoft (R) Optimizing Compiler Version 13.10.3077

    TITLE   test.c
    .386P
include listing.inc
if @Version gt 510
.model FLAT
else
_TEXT   SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT   ENDS
_DATA   SEGMENT DWORD USE32 PUBLIC 'DATA'
_DATA   ENDS
CONST   SEGMENT DWORD USE32 PUBLIC 'CONST'
CONST   ENDS
_BSS    SEGMENT DWORD USE32 PUBLIC 'BSS'
_BSS    ENDS
$$SYMBOLS   SEGMENT BYTE USE32 'DEBSYM'
$$SYMBOLS   ENDS
_TLS    SEGMENT DWORD USE32 PUBLIC 'TLS'
_TLS    ENDS
FLAT    GROUP _DATA, CONST, _BSS
    ASSUME  CS: FLAT, DS: FLAT, SS: FLAT
endif

INCLUDELIB LIBC
INCLUDELIB OLDNAMES

_DATA   SEGMENT
$SG794  DB  09H, 'This is a string containing %d escape sequences', 0aH
    DB  00H
_DATA   ENDS
PUBLIC  _main
EXTRN   _printf:NEAR
; Function compile flags: /Odt
_TEXT   SEGMENT
_count$ = -4                        ; size = 4
_main   PROC NEAR
; File c:\documents and settings\gregory  lyon\local settings\temp\test.c
; Line 4
  00000 55       push    ebp
  00001 8b ec        mov     ebp, esp
  00003 51       push    ecx
; Line 5
  00004 c7 45 fc 02 00
    00 00        mov     DWORD PTR _count$[ebp], 2
; Line 7
  0000b 8b 45 fc     mov     eax, DWORD PTR _count$[ebp]
  0000e 50       push    eax
  0000f 68 00 00 00 00   push    OFFSET FLAT:$SG794
  00014 e8 00 00 00 00   call    _printf
  00019 83 c4 08     add     esp, 8
; Line 9
  0001c 33 c0        xor     eax, eax
; Line 10
  0001e 8b e5        mov     esp, ebp
  00020 5d       pop     ebp
  00021 c3       ret     0
_main   ENDP
_TEXT   ENDS
END


So, in MASM we need to convert the escape sequences to their ASCII values before passing a string to the C Run-Time function. This works.

.586
.MODEL FLAT, stdcall
option casemap:none

include windows.inc

include kernel32.inc
include user32.inc
include masm32.inc
include msvcrt.inc

include c:\masm32\macros\macros.asm

includelib kernel32.lib
includelib user32.lib
includelib masm32.lib
includelib msvcrt.lib

.DATA

    count   DWORD 2
    String  BYTE  9, "This is a string containing %d escape sequences", 10, 0

.CODE

start:

    invoke crt_printf, ADDR String, count
   
    invoke ExitProcess, 0

end start



the output is:

        This is a string containing 2 escape sequences


Note that the format specifier ( %d ) is passed the same as it is in C.


hutch--

This test piece may solve the problem with any of the text functions that embed newline and tab characters. This is just a simple test piece to make sure it works but its probably able to be used as a general purpose string macro to give this support to any string display function that requires it.

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

comment * -----------------------------------------------------
                        Build this  template with
                       "CONSOLE ASSEMBLE AND LINK"
        ----------------------------------------------------- *

    cprintf MACRO txt:VARARG
      LOCAL buffer,lbuf,rbuf,sln,flag1,tmp
      flag1 = 0
      buffer equ <>
      lbuf equ <>
      rbuf equ <>

      FORC char,<txt>
        IF flag1 NE 0
          IFIDN <char>,<n>
            buffer CATSTR buffer,<",13,10,">
            flag1 = 0
            goto lpend
          ENDIF
          IFIDN <char>,<t>
            buffer CATSTR buffer,<",9,">
            flag1 = 0
            goto lpend
          ENDIF
        ENDIF
        IFIDN <char>,<\>
          flag1 = 1
          goto lpend
        ENDIF
        buffer CATSTR buffer,<char>
    :lpend
      ENDM
        buffer CATSTR buffer,<,0,0,0>   ;; append trailing zeros
        cpos INSTR buffer,<"",>         ;; chomp off the first empty quotes & comma
        IF cpos EQ 1
          buffer SUBSTR buffer,4
        ENDIF
      :reloop
        sln SIZESTR buffer
        cpos INSTR buffer,<"",>
          IF cpos EQ 0
            goto done
          ENDIF
        lbuf SUBSTR buffer,1,cpos-1
        rbuf SUBSTR buffer,cpos+3
        buffer equ <>
        buffer CATSTR lbuf,rbuf
        goto reloop
      :done
        sln SIZESTR buffer
        buffer SUBSTR buffer,1,sln-4
        .data
          tmp db buffer
        .code
        print OFFSET tmp
    ENDM

    .code

start:
   
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

    call main
    inkey
    exit

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

main proc

    cprintf "\tThis is a\n\ttest\n\tof embedded tab\n\tand newline characters\n"

    ret

main endp

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

end start
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

GregL

#101
Hutch,

That's cool, I was thinking about writing a macro to do that. You beat me to it. So if a person wants to use C-style escape sequences, they can.  :thumbu

One thing I noticed about what the C compiler does is '\n' is replaced only with 10, and not with 13, 10. How about making '\n' = 10, '\r' = 13 in the macro? Not that it makes a great deal of difference, but it would match the C implementation.

Escape Sequences


GregL

Hutch,

Did you convert the sscanf conversion procedures I wrote to macros? I got the impression you were doing that, so I never did it. If you didn't, I would be glad to do it.

I was working on a program today where a macro would work better than the procedure, it got me thinking about this.


hutch--

Greg,

I have been a bit bogged down of late but I thought the sscanf code was a very good candidate for a set of macros that would compliment the other conversions you have already finished. I had a quick play with the naming for the complete set and using something like,


a = ascii
h = hex
fl = float or fp

2 = to

data size

sb = signed byte
ub = unsigned byte


A naming scheme of something like this makes te whole lot far easier to remember
etc ....

I was just a bit worried that the workload was a bit high when you have other stuff to do.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

GregL

#104
sscanf conversion macros.

Any suggestions for improvement are welcome.

(the test program requires the newest sprintf conversion macros).



[attachment deleted by admin]