LOW LEVEL C - What else?

Started by frktons, June 03, 2010, 09:26:13 AM

Previous topic - Next topic

frktons

As far as I have got from my C readings, many things I would like my pgms to perform
are not possible or very complicated with C ANSI Libs.

For example, I want to set up a standard win32 console with DOS characteristics: fixed size (80 x 25),
colors, direct positioning of output on it (rows and cols), validated input key after key, and so on.

What I have to do is just using some win32 APIs for everything, so the C language is a good
way for calling Windows API that were written with a C in their mind.  :P

This means a simple program like

#include <stdio.h>

int main(void)
{
   printf("Let's do something\n");
   return 0;
}


is going to take some 30-40 lines to be properly accomplished
with fixed size console, colors, positioning on the screen and so on.

The good news is: when I've done it, I can use the same function from
then forward, and the next time it'll take considerable less time and
effort to do something similar.  :lol

What's your C experts opininion?

This should be the  code for buiding a win32 console fixed size:



#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

HANDLE wHnd;    // Handle to write to the console.
HANDLE rHnd;    // Handle to read from the console.

int main(int argc, char *argv[])
{
   
    // Set up the handles for reading/writing:
    wHnd = GetStdHandle(STD_OUTPUT_HANDLE);
    rHnd = GetStdHandle(STD_INPUT_HANDLE);

    // Change the window title:
    SetConsoleTitle("Win32 Console 80 x 25 Fixed Size");

    // Set up the required window size:
    SMALL_RECT windowSize = {0, 0, 79, 24};
   
    // Change the console window size:
    SetConsoleWindowInfo(wHnd, TRUE, &windowSize);

   
    // Create a COORD to hold the buffer size:
    COORD bufferSize = {80, 25};

    // Change the internal buffer size:
    SetConsoleScreenBufferSize(wHnd, bufferSize);

    getchar();
    return 0;
}



How do I compile it with Pelle's C? It gives a lot of errors when I try.  ::)

Thanks

Frank
Mind is like a parachute. You know what to do in order to use it :-)

TmX

Project -> Project Options -> Compiler -> check the "Enable Microsoft extensions"

frktons

Quote from: TmX on June 03, 2010, 01:11:49 PM
Project -> Project Options -> Compiler -> check the "Enable Microsoft extensions"

Thanks TmX. Now It works  :U

I can go on adding the more needed APIs  :P

Frank
Mind is like a parachute. You know what to do in order to use it :-)

frktons

A couple of APIs later:


// ---------------------------------------------------------------------------------------------------------------
// Playing with Win32 Console.
// We first allocate a fixed size DOS style 80 x 25 Console, then we select colors
// and print some text into it at a specified location (cols, rows)
// ---------------------------------------------------------------------------------------------------------------
// To select the colors of the console we first use the system() call to the
// command "color" passing it the combination background/foreground color
// according to the following table:
// ----------  Italian Consoles :-) --------------------
//   0 = Nero                         
//   1 = Blu scuro                 
//   2 = Verde                       
//   3 = Verde acqua           
//   4 = Bordeaux                 
//   5 = Viola                         
//   6 = Verde oliva               
//   7 = Grigio chiaro             
//    8 = Grigio
//    9 = Blu
//    A = Verde limone
//    B = Azzurro
//    C = Rosso
//    D = Fucsia
//    E = Giallo
//    F = Bianco
//----------  English Consoles :-) --------------------
//  0 = Black           8 = Gray
//  1 = Blue            9 = Light Blue
//  2 = Green         a = Light Green
//  3 = Aqua           b = Light Aqua
//  4 = Red             c = Light Red
//  5 = Purple         d = Light Purple
//  6 = Yellow         e = Light Yellow
//  7 = White           f = Bright White
// ---------------------------------------------------------------------------------------------------------------
// Afterwhile, we'll use the Windows APIs to perform the same operation.
// Once the colors have been set, we position the cursor at the centre of
// the screen and display the famous sentence "Let's do something".
//----------------------------------------------------------------------------------------------------------------
#include <windows.h>
#include <stdio.h>

HANDLE wHnd;    // Handle to write to the console.
HANDLE rHnd;    // Handle to read from the console.

void Console80x25(void);
void DisplayAt(int x, int y, char *StringBuffer, int len);

int main(int argc, char *argv[])
{
   
    Console80x25();
    system("color 1e");
    DisplayAt(32, 12, "Let\'s do something\n", 19);

    getchar();
    return 0;
}

void Console80x25()
{
    // Set up the handles for reading/writing:
    wHnd = GetStdHandle(STD_OUTPUT_HANDLE);
    rHnd = GetStdHandle(STD_INPUT_HANDLE);

    // Change the window title:
    SetConsoleTitle("Win32 Console 80 x 25 Fixed Size");

    // Set up the required window size:
    SMALL_RECT windowSize = {0, 0, 79, 24};
   
    // Change the console window size:
    SetConsoleWindowInfo(wHnd, TRUE, &windowSize);

   
    // Create a COORD to hold the buffer size:
    COORD bufferSize = {80, 25};

    // Change the internal buffer size:
    SetConsoleScreenBufferSize(wHnd, bufferSize);
}

// Console display at a particular screen position.
void DisplayAt(int x, int y, char *StringBuffer, int len)
{
    DWORD n_of_chars;
    COORD position = {x, y};
    SetConsoleCursorPosition(wHnd, position);
    WriteConsole(wHnd, StringBuffer, len, &n_of_chars, NULL);
    return;
}



Including the <stdio.h> for getchar() bloated the size of the EXE 4 Kb.  :(

How do I get rid of these unacceptable burden? Pragma directive again?  ::)

P.S. Oh well I added the two infamous lines:

#undef getchar
#pragma comment(lib, "\\masm32\\lib\\msvcrt.lib")


and it shrinked from 19K to 9K  :lol

Could anyone translate it into MASM just to see how it can
be done and how big it'll be?

Thanks

Frank
Mind is like a parachute. You know what to do in order to use it :-)

redskull

.EXE size of 2560  :U


.386
.model flat, STDCALL
option casemap:none

include C:\prog\include\windows.inc

include C:\prog\include\kernel32.inc
includelib ".\lib\kernel32.lib"
include C:\prog\include\user32.inc
includelib ".\lib\user32.lib"



Console80x25 PROTO
DisplayAt    PROTO x:DWORD, y:DWORD, StringBuffer:DWORD, len:DWORD

.data?
wHnd        HANDLE ?
rHnd        HANDLE ?
inpbyte     DWORD ?

.data
ConTitle    db "Win32 Console 80 x 25 Fixed Size", 0
DispStr     db "Let's do something",10,13
.code
start:

    invoke AllocConsole

    invoke Console80x25

    invoke SetConsoleTextAttribute, wHnd, (BACKGROUND_BLUE OR  FOREGROUND_BLUE OR FOREGROUND_GREEN)
   
    invoke DisplayAt, 32, 12, ADDR DispStr, SIZEOF DispStr

    invoke ReadConsole, rHnd, ADDR inpbyte, 1, NULL, NULL

    invoke ExitProcess, 0

    ret
   

Console80x25 PROC

    LOCAL windowSize:SMALL_RECT
    LOCAL bufferSize:COORD

    mov windowSize.Left, 0
    mov windowSize.Right, 0
    mov windowSize.Top, 79
    mov windowSize.Bottom, 24
   

    mov bufferSize.x, 80
    mov bufferSize.y, 25
   
    invoke GetStdHandle, STD_OUTPUT_HANDLE
    mov wHnd,eax
   
    invoke GetStdHandle, STD_INPUT_HANDLE
    mov rHnd,eax
   
    invoke SetConsoleTitle, ADDR ConTitle
   
    invoke SetConsoleWindowInfo, wHnd, TRUE, ADDR windowSize

    invoke SetConsoleScreenBufferSize, wHnd, DWORD PTR bufferSize

    ret

Console80x25 ENDP

DisplayAt PROC x:DWORD, y:DWORD, StringBuffer:DWORD, len:DWORD
   
    LOCAL n_of_chars:DWORD
    LOCAL position:COORD
   
    mov eax, x
    mov position.x, ax
    mov eax, y
    mov position.y, ax
   
    invoke SetConsoleCursorPosition, wHnd, DWORD PTR position
    invoke WriteConsole, wHnd, StringBuffer, len, ADDR n_of_chars, NULL
   
    ret
DisplayAt ENDP

end start


-r
Strange women, lying in ponds, distributing swords, is no basis for a system of government

frktons

That's really great - thanks RedSkull  :U

In my pc it is still a little bloated: 3.00 KB (3.072 byte)  :lol

I used:


include     C:\masm32\include\kernel32.inc
includelib C:\masm32\lib\kernel32.lib
include     C:\masm32\include\user32.inc
includelib C:\masm32\lib\user32.lib


instead of your:


include C:\prog\include\kernel32.inc
includelib ".\lib\kernel32.lib"
include C:\prog\include\user32.inc
includelib ".\lib\user32.lib"


Is it the same?

Frank
Mind is like a parachute. You know what to do in order to use it :-)

clive

C:\MASM>\tools\masm615\ml -coff console.asm -link /SUBSYSTEM:CONSOLE /ALIGN:16
Microsoft (R) Macro Assembler Version 6.15.8803
Copyright (C) Microsoft Corp 1981-2000.  All rights reserved.

Assembling: console.asm
Microsoft (R) Incremental Linker Version 6.00.8168
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

/SUBSYSTEM:CONSOLE /ALIGN:16
"console.obj"
"/OUT:console.exe"
LINK : warning LNK4108: /ALIGN specified without /DRIVER or /VXD; image may not
run

C:\MASM>dir console.exe
Volume in drive C is Windows
Volume Serial Number is 6801-E078

Directory of C:\MASM

06/03/2010  01:16 PM             1,296 console.exe
               1 File(s)          1,296 bytes
               0 Dir(s)  58,776,809,472 bytes free
It could be a random act of randomness. Those happen a lot as well.

frktons

Hi Clive  :U

You mean that:

ml -coff console.asm -link /SUBSYSTEM:CONSOLE /ALIGN:16


just using the /ALIGN:16 reduces the size of the EXE file?

Well the warning

LINK : warning LNK4108: /ALIGN specified without /DRIVER; image may not run


was a good one, on my pc it refuses to run  ::)

Any idea?

Mind is like a parachute. You know what to do in order to use it :-)

redskull

Quote from: frktons on June 03, 2010, 06:07:24 PMIs it the same?

Close enough; i use the tools and libraries from the most current SDK (7), and not the ones from MASM32 package.  Also, I linked it as a WINDOWS application; if you link it as a CONSOLE, and then launch it from cmd (which causes it to inherit the same one), i predict it will not do what you want, and just overwrite the text that is there

-r
Strange women, lying in ponds, distributing swords, is no basis for a system of government

clive

Well the default alignment for the 6.00 linker is 4K, which makes the EXE 16K

As /SUBSYSTEM:WINDOWS, my bad

C:\MASM>\tools\masm615\ml -coff console.asm -link /SUBSYSTEM:WINDOWS
Microsoft (R) Macro Assembler Version 6.15.8803
Copyright (C) Microsoft Corp 1981-2000.  All rights reserved.

Assembling: console.asm
Microsoft (R) Incremental Linker Version 6.00.8168
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

/SUBSYSTEM:WINDOWS
"console.obj"
"/OUT:console.exe"

C:\MASM>dir console.exe
Volume in drive C is Windows
Volume Serial Number is 6801-E078

Directory of C:\MASM

06/03/2010  01:28 PM            16,384 console.exe
               1 File(s)         16,384 bytes
               0 Dir(s)  58,772,316,160 bytes free


C:\MASM>\tools\masm615\ml -coff console.asm -link /SUBSYSTEM:WINDOWS /ALIGN:16
Microsoft (R) Macro Assembler Version 6.15.8803
Copyright (C) Microsoft Corp 1981-2000.  All rights reserved.

Assembling: console.asm
Microsoft (R) Incremental Linker Version 6.00.8168
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

/SUBSYSTEM:WINDOWS /ALIGN:16
"console.obj"
"/OUT:console.exe"
LINK : warning LNK4108: /ALIGN specified without /DRIVER or /VXD; image may not
run

C:\MASM>dir console.exe
Volume in drive C is Windows
Volume Serial Number is 6801-E078

Directory of C:\MASM

06/03/2010  01:27 PM             1,296 console.exe
               1 File(s)          1,296 bytes
               0 Dir(s)  58,772,725,760 bytes free
It could be a random act of randomness. Those happen a lot as well.

frktons

Quote from: redskull on June 03, 2010, 06:26:08 PM
Quote from: frktons on June 03, 2010, 06:07:24 PMIs it the same?

Close enough; i use the tools and libraries from the most current SDK (7), and not the ones from MASM32 package.  Also, I linked it as a WINDOWS application; if you link it as a CONSOLE, and then launch it from cmd (which causes it to inherit the same one), i predict it will not do what you want, and just overwrite the text that is there

-r

Well I launched from cmd and it run without problem.  :U
Black screen and cyan on blue string displayed at the correct position.
Well I checked, you were right, it overwrites the existing  text.
Maybe a CLS would help  :lol

@Clive:
The warning

LINK : warning LNK4108: /ALIGN specified without /DRIVER; image may not run


was a good one, on my pc it refuses to run  ::)

Any idea?



Mind is like a parachute. You know what to do in order to use it :-)

redskull

Here's the 9.0 verions. Suppsoedly the alignment is still 4K, so I'm not sure where it's different...


C:\prog>ml /c /coff console.asm
Microsoft (R) Macro Assembler Version 9.00.21022.08
Copyright (C) Microsoft Corporation.  All rights reserved.

Assembling: console.asm

C:\prog>link /SUBSYSTEM:WINDOWS console.obj
Microsoft (R) Incremental Linker Version 9.00.21022.08
Copyright (C) Microsoft Corporation.  All rights reserved.


C:\prog>dir console.exe
Volume in drive C is IS-CUB3
Volume Serial Number is 4C6E-1410

Directory of C:\prog

06/03/2010  02:41 PM             2,560 console.exe
               1 File(s)          2,560 bytes
               0 Dir(s)  19,155,349,504 bytes free

C:\prog>
Strange women, lying in ponds, distributing swords, is no basis for a system of government

frktons

#12
Quote from: redskull on June 03, 2010, 06:44:51 PM
Here's the 9.0 verions. Suppsoedly the alignment is still 4K, so I'm not sure where it's different...


C:\prog>ml /c /coff console.asm

C:\prog>link /SUBSYSTEM:WINDOWS console.obj


I used the same instructions and now the console displayed is a new one,
and the size is still 3072 bytes. I used ML v.10 / LINK v.10 from VS2010.

The different size could depend on the different libs you are including or on
how windows 7 ultimate 64 bit manages the whole.

Anyway 3K versus 9K of the C shrinked version is still a good gain.  :P

Mind is like a parachute. You know what to do in order to use it :-)

frktons

Info update:

On win xp pro sp2 the size of the exe is the same of yours, so it probably depends
on the file system used. I used the same MASM32 package.

I have NTFS file system in both pc, on win7 I used a 4K cluster size to format the hard disk,
on win xp pro I don't know, it was already formatted.
Mind is like a parachute. You know what to do in order to use it :-)

redskull

That's odd, that the exact code built the same way with the same tools would be slightly different between XP and 7; after all, the file size should be reported the same, even if the "size on disk" is different.  For the record, I use XP with a a 4K NTFS as well.  I can't for the life of me think why they would be different, especialyl considering it's under a single cluster anyway.  I'd be interested to see if there are discrepancies between the same exact file; i.e. assemble and link on XP, and then copy the EXE to 7 to see what it says.

-r
Strange women, lying in ponds, distributing swords, is no basis for a system of government