Click to See Complete Forum and Search --> : helo on converting some c++ codes into assembly


Master.
May 26th, 2011, 11:42 AM
hello all
im seeking help on converting two lines of c++ codes into its windows assembly counter parts
any help is greatly appreciated

GetKeyboardState((LPBYTE)&keyState);
if( (bState && !(keyState[VK_CAPITAL] & 1)) || (!bState && (keyState[VK_CAPITAL] & 1)) )

Thanks in advance

Joeman
May 26th, 2011, 12:10 PM
Have your tried using a compiler to generate assembly code? I know it won't look pretty, but it will at least give you a working example to start off with.

for ex gcc will output this

#include "windows.h"

void SetCapitalKey( int bState )
{
BYTE keyState[ 256 ];
GetKeyboardState((LPBYTE)&keyState);
if( (bState && !(keyState[VK_CAPITAL] & 1)) || (!bState && (keyState[VK_CAPITAL] & 1)) )
{
}
}
.file "file.c"
.intel_syntax noprefix
.text
.globl _SetCapitalKey
.def _SetCapitalKey; .scl 2; .type 32; .endef
_SetCapitalKey:
push ebp
mov ebp, esp
sub esp, 280
lea eax, [ebp-264]
mov DWORD PTR [esp], eax
call _GetKeyboardState@4
sub esp, 4
cmp DWORD PTR [ebp+8], 0
je L2
mov al, BYTE PTR [ebp-244]
movzx eax, al
and eax, 1
test eax, eax
je L3
L2:
cmp DWORD PTR [ebp+8], 0
jne L1
mov al, BYTE PTR [ebp-244]
movzx eax, al
and eax, 1
test al, al
je L1
L3:
// STATEMENT CODE HERE
L1:
leave
ret
.def _GetKeyboardState@4; .scl 2; .type 32; .endef
You can now modify this to what ever you like.

Master.
May 26th, 2011, 01:02 PM
Have your tried using a compiler to generate assembly code? I know it won't look pretty, but it will at least give you a working example to start off with.

for ex gcc will output this

#include "windows.h"

void SetCapitalKey( int bState )
{
BYTE keyState[ 256 ];
GetKeyboardState((LPBYTE)&keyState);
if( (bState && !(keyState[VK_CAPITAL] & 1)) || (!bState && (keyState[VK_CAPITAL] & 1)) )
{
}
}
.file "file.c"
.intel_syntax noprefix
.text
.globl _SetCapitalKey
.def _SetCapitalKey; .scl 2; .type 32; .endef
_SetCapitalKey:
push ebp
mov ebp, esp
sub esp, 280
lea eax, [ebp-264]
mov DWORD PTR [esp], eax
call _GetKeyboardState@4
sub esp, 4
cmp DWORD PTR [ebp+8], 0
je L2
mov al, BYTE PTR [ebp-244]
movzx eax, al
and eax, 1
test eax, eax
je L3
L2:
cmp DWORD PTR [ebp+8], 0
jne L1
mov al, BYTE PTR [ebp-244]
movzx eax, al
and eax, 1
test al, al
je L1
L3:
// STATEMENT CODE HERE
L1:
leave
ret
.def _GetKeyboardState@4; .scl 2; .type 32; .endef
You can now modify this to what ever you like.
Thanks a million dear Joeman but i got confused !!!
i was more looking for things more readable . well i wrote sth , but because im not familiare with windows assembly , im stuck at some parts . to convert the given c++ codes, i already wrote these but im not sure which parts are fine and which are not :
:
BYTE keyState[256];
keyState db 256 dup(?)GetKeyboardState((LPBYTE)&keyState);
invoke GetKeyboardState,keyState //some help here ??!! what should i do about that LPBYTE ?!
keybd_event( VK_CAPITAL,0x45,KEYEVENTF_EXTENDEDKEY | 0,0 );
invoke keybd_event VK_CAPITAL,0x45,KEYEVENTF_EXTENDEDKEY | 0,0keybd_event( VK_CAPITAL,0x45,KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,0);
invoke keybd_event VK_CAPITAL,0x45,KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,0

and for that if statement im completely clueless !

and by the way , how do you get a assembly source code in gcc? (im using codeblocks , where should i go to configure gcc to generate asm files? )

Joeman
May 26th, 2011, 01:42 PM
I know of 2 ways:

In the menu go to Project -> Build options... -> Compiler settings tab -> Other options tab.

Place
-save-temps
-masm=intel

The other way is to modify a cpp individually by right clicking on the cpp file in the manager window and clicking Properties.... This will load up the property window and go to the Advance tab. Check "use custom command to build this file". Add "$compiler $options $includes -c $file -o $object -save-temp -masm=intel"

What assembler are you using?

Master.
May 26th, 2011, 10:10 PM
thanks :)
im using Masm 6.14 .
------------
i generated an assembly source code out of my c++ project using visual studio
but i have couple of problems with compiling the asm source code.
the first one is there is a listing.inc file missing ! i dont know where to get it or how to make one !
visual studio made the source code and i have no idea where that came from!
the second problem is that i dont know what those wierd looking symbols mean! i would appreciate anyone helping me on figuring these weird symbols :)
and finally this is the C++ code and its asm counter part :

C++:

#include <windows.h>

void SetKey( BOOL bState,int keyID )
{
BYTE keyState[256];

GetKeyboardState((LPBYTE)&keyState);

if( (bState && !(keyState[keyID] & 1)) || (!bState && (keyState[keyID] & 1)) )
{
keybd_event( keyID,0x45,KEYEVENTF_EXTENDEDKEY | 0,0 );
// Simulate a key release
keybd_event( keyID,0x45,KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,0);
}
}


int main()
{
while (true)
{

SetKey(TRUE,20);//capsluck
SetKey(TRUE,144);//numluck
SetKey(TRUE,145);//scrolluck

for(int i = 0; i < 99999999;i++);

SetKey(FALSE,20);//capsluck
SetKey(FALSE,144);//numluck
SetKey(FALSE,145);//scrolluck

for(int i = 0; i < 99999999;i++);

}

return 0;
}



and the generated asm source code :

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

TITLE d:\Documents and Settings\Master\Desktop\eli asm\cpp\CAPS\CAPS\main.cpp
.686P
.XMM
include listing.inc
.model flat

INCLUDELIB MSVCRTD
INCLUDELIB OLDNAMES

PUBLIC __$ArrayPad$
PUBLIC ?SetKey@@YAXHH@Z ; SetKey
EXTRN __imp__keybd_event@16:PROC
EXTRN __imp__GetKeyboardState@4:PROC
EXTRN ___security_cookie:DWORD
EXTRN @__security_check_cookie@4:PROC
EXTRN @_RTC_CheckStackVars@8:PROC
EXTRN __RTC_CheckEsp:PROC
EXTRN __RTC_Shutdown:PROC
EXTRN __RTC_InitBase:PROC
; COMDAT rtc$TMZ
; File d:\documents and settings\master\desktop\eli asm\cpp\caps\caps\main.cpp
rtc$TMZ SEGMENT
__RTC_Shutdown.rtc$TMZ DD FLAT:__RTC_Shutdown
rtc$TMZ ENDS
; COMDAT rtc$IMZ
rtc$IMZ SEGMENT
__RTC_InitBase.rtc$IMZ DD FLAT:__RTC_InitBase
; Function compile flags: /Odtp /RTCsu /ZI
rtc$IMZ ENDS
; COMDAT ?SetKey@@YAXHH@Z
_TEXT SEGMENT
_keyState$ = -264 ; size = 256
__$ArrayPad$ = -4 ; size = 4
_bState$ = 8 ; size = 4
_keyID$ = 12 ; size = 4
?SetKey@@YAXHH@Z PROC ; SetKey, COMDAT

push ebp
mov ebp, esp
sub esp, 460 ; 000001ccH
push ebx
push esi
push edi
lea edi, DWORD PTR [ebp-460]
mov ecx, 115 ; 00000073H
mov eax, -858993460 ; ccccccccH
rep stosd
mov eax, DWORD PTR ___security_cookie
xor eax, ebp
mov DWORD PTR __$ArrayPad$[ebp], eax

mov esi, esp
lea eax, DWORD PTR _keyState$[ebp]
push eax
call DWORD PTR __imp__GetKeyboardState@4
cmp esi, esp
call __RTC_CheckEsp

cmp DWORD PTR _bState$[ebp], 0
je SHORT $LN1@SetKey
mov eax, DWORD PTR _keyID$[ebp]
movzx ecx, BYTE PTR _keyState$[ebp+eax]
and ecx, 1
je SHORT $LN2@SetKey
$LN1@SetKey:
cmp DWORD PTR _bState$[ebp], 0
jne SHORT $LN4@SetKey
mov eax, DWORD PTR _keyID$[ebp]
movzx ecx, BYTE PTR _keyState$[ebp+eax]
and ecx, 1
je SHORT $LN4@SetKey
$LN2@SetKey:

mov esi, esp
push 0
push 1
push 69 ; 00000045H
movzx eax, BYTE PTR _keyID$[ebp]
push eax
call DWORD PTR __imp__keybd_event@16
cmp esi, esp
call __RTC_CheckEsp

mov esi, esp
push 0
push 3
push 69 ; 00000045H
movzx eax, BYTE PTR _keyID$[ebp]
push eax
call DWORD PTR __imp__keybd_event@16
cmp esi, esp
call __RTC_CheckEsp
$LN4@SetKey:

push edx
mov ecx, ebp
push eax
lea edx, DWORD PTR $LN8@SetKey
call @_RTC_CheckStackVars@8
pop eax
pop edx
pop edi
pop esi
pop ebx
mov ecx, DWORD PTR __$ArrayPad$[ebp]
xor ecx, ebp
call @__security_check_cookie@4
add esp, 460 ; 000001ccH
cmp ebp, esp
call __RTC_CheckEsp
mov esp, ebp
pop ebp
ret 0
npad 3
$LN8@SetKey:
DD 1
DD $LN7@SetKey
$LN7@SetKey:
DD -264 ; fffffef8H
DD 256 ; 00000100H
DD $LN6@SetKey
$LN6@SetKey:
DB 107 ; 0000006bH
DB 101 ; 00000065H
DB 121 ; 00000079H
DB 83 ; 00000053H
DB 116 ; 00000074H
DB 97 ; 00000061H
DB 116 ; 00000074H
DB 101 ; 00000065H
DB 0
?SetKey@@YAXHH@Z ENDP ; SetKey
_TEXT ENDS
PUBLIC _main

_TEXT SEGMENT
_i$62694 = -20 ; size = 4
_i$62690 = -8 ; size = 4
_main PROC ; COMDAT

push ebp
mov ebp, esp
sub esp, 216 ; 000000d8H
push ebx
push esi
push edi
lea edi, DWORD PTR [ebp-216]
mov ecx, 54 ; 00000036H
mov eax, -858993460 ; ccccccccH
rep stosd
$LN8@main:

mov eax, 1
test eax, eax
je $LN7@main

push 20 ; 00000014H
push 1
call ?SetKey@@YAXHH@Z ; SetKey
add esp, 8

push 144 ; 00000090H
push 1
call ?SetKey@@YAXHH@Z ; SetKey
add esp, 8

push 145 ; 00000091H
push 1
call ?SetKey@@YAXHH@Z ; SetKey
add esp, 8

mov DWORD PTR _i$62690[ebp], 0
jmp SHORT $LN6@main
$LN5@main:
mov eax, DWORD PTR _i$62690[ebp]
add eax, 1
mov DWORD PTR _i$62690[ebp], eax
$LN6@main:
cmp DWORD PTR _i$62690[ebp], 99999999 ; 05f5e0ffH
jge SHORT $LN4@main
jmp SHORT $LN5@main
$LN4@main:

push 20 ; 00000014H
push 0
call ?SetKey@@YAXHH@Z ; SetKey
add esp, 8


push 144 ; 00000090H
push 0
call ?SetKey@@YAXHH@Z ; SetKey
add esp, 8

push 145 ; 00000091H
push 0
call ?SetKey@@YAXHH@Z ; SetKey
add esp, 8

mov DWORD PTR _i$62694[ebp], 0
jmp SHORT $LN3@main
$LN2@main:
mov eax, DWORD PTR _i$62694[ebp]
add eax, 1
mov DWORD PTR _i$62694[ebp], eax
$LN3@main:
cmp DWORD PTR _i$62694[ebp], 99999999 ; 05f5e0ffH
jge SHORT $LN1@main
jmp SHORT $LN2@main
$LN1@main:

jmp $LN8@main
$LN7@main:

xor eax, eax

pop edi
pop esi
pop ebx
add esp, 216 ; 000000d8H
cmp ebp, esp
call __RTC_CheckEsp
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END

Joeman
May 26th, 2011, 11:36 PM
Unless you can get mvsc to ouput the assembly without so much added code, I would recommend just starting from scrap :) or just read between the lines.
I am not for sure how masm is setup for its includes, but it should be automatic?
I don't know how much it will help you, but this is that if statement converted to nasm :D
%define VK_CONTROL 0x11

global _main
extern _GetKeyboardState@4
extern _printf
section .data
State: times 256 db 0
bState: db 0
section .text
SuccessMsg: db "Check Valid", 0
FailedMsg: db "Check Invalid", 0
_main:
push State
call _GetKeyboardState@4

;if( (bState && !(keyState[ VK_CONTROL ] & 1)) || (!bState && (keyState[ VK_CONTROL] & 1)) )
IF:
cmp BYTE[ bState ], 0
je OR
mov al, BYTE[ State + VK_CONTROL ]
and al, 1
test al, al
je PASSED
OR:
cmp BYTE[ bState ], 0
jne FAILED
mov al, BYTE[ State + VK_CONTROL ]
and al, 1
test al, al
je FAILED
PASSED:
push dword SuccessMsg
call _printf
add esp, 4
FAILED:
DONE:

mov eax, 0
retI will check into masm, but that will require some time... I suggest you read some more :D

Master.
May 27th, 2011, 05:28 AM
Unless you can get mvsc to ouput the assembly without so much added code, I would recommend just starting from scrap :) or just read between the lines.
I am not for sure how masm is setup for its includes, but it should be automatic?
I don't know how much it will help you, but this is that if statement converted to nasm :D
%define VK_CONTROL 0x11

global _main
extern _GetKeyboardState@4
extern _printf
section .data
State: times 256 db 0
bState: db 0
section .text
SuccessMsg: db "Check Valid", 0
FailedMsg: db "Check Invalid", 0
_main:
push State
call _GetKeyboardState@4

;if( (bState && !(keyState[ VK_CONTROL ] & 1)) || (!bState && (keyState[ VK_CONTROL] & 1)) )
IF:
cmp BYTE[ bState ], 0
je OR
mov al, BYTE[ State + VK_CONTROL ]
and al, 1
test al, al
je PASSED
OR:
cmp BYTE[ bState ], 0
jne FAILED
mov al, BYTE[ State + VK_CONTROL ]
and al, 1
test al, al
je FAILED
PASSED:
push dword SuccessMsg
call _printf
add esp, 4
FAILED:
DONE:

mov eax, 0
retI will check into masm, but that will require some time... I suggest you read some more :D
thank you very much :)
couldnt use that :( , that made me stick to that visual studio generated code , but this time i could strip some more unused stuff (such as security tokens and RTC stuff which i dont know what it is !!)
any way , here is the code , i could successfully compile this , but on liking process i face some errors :(
anyhelp is greatly appreciated

here is the latest asm code i came up with (more easier to read and maintain compared to the former one !) :) :

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

TITLE d:\Documents and Settings\Master\Desktop\eli asm\cpp\CAPS\CAPS\main.cpp
.686P
.XMM
;include listing.inc
.model flat

includelib \masm32\lib\user32.lib
includelib \masm32\lib\setupapi.lib

INCLUDELIB MSVCRTD
INCLUDELIB OLDNAMES

PUBLIC ?SetKey@@YAXHH@Z ; SetKey
EXTRN __imp__keybd_event@16:PROC
EXTRN __imp__GetKeyboardState@4:PROC
; Function compile flags: /Odtp /ZI
; File d:\documents and settings\master\desktop\eli asm\cpp\caps\caps\main.cpp
; COMDAT ?SetKey@@YAXHH@Z
_TEXT SEGMENT
_keyState$ = -256 ; size = 256
_bState$ = 8 ; size = 4
_keyID$ = 12 ; size = 4
?SetKey@@YAXHH@Z PROC ; SetKey, COMDAT

push ebp
mov ebp, esp
sub esp, 320 ; 00000140H
push ebx
push esi
push edi

lea eax, DWORD PTR _keyState$[ebp]
push eax
call DWORD PTR __imp__GetKeyboardState@4


cmp DWORD PTR _bState$[ebp], 0
je SHORT $LN1@SetKey
mov eax, DWORD PTR _keyID$[ebp]
movzx ecx, BYTE PTR _keyState$[ebp+eax]
and ecx, 1
je SHORT $LN2@SetKey
$LN1@SetKey:
cmp DWORD PTR _bState$[ebp], 0
jne SHORT $LN4@SetKey
mov eax, DWORD PTR _keyID$[ebp]
movzx ecx, BYTE PTR _keyState$[ebp+eax]
and ecx, 1
je SHORT $LN4@SetKey
$LN2@SetKey:

push 0
push 1
push 69 ; 00000045H
movzx eax, BYTE PTR _keyID$[ebp]
push eax
call DWORD PTR __imp__keybd_event@16

push 0
push 3
push 69 ; 00000045H
movzx eax, BYTE PTR _keyID$[ebp]
push eax
call DWORD PTR __imp__keybd_event@16
$LN4@SetKey:

pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret 0
?SetKey@@YAXHH@Z ENDP ; SetKey
_TEXT ENDS
PUBLIC _main
; Function compile flags: /Odtp /ZI
; COMDAT _main
_TEXT SEGMENT
_i$62694 = -8 ; size = 4
_i$62690 = -4 ; size = 4
_main PROC ; COMDAT

push ebp
mov ebp, esp
sub esp, 72 ; 00000048H
push ebx
push esi
push edi
$LN8@main:

mov eax, 1
test eax, eax
je $LN7@main

push 20 ; 00000014H
push 1
call ?SetKey@@YAXHH@Z ; SetKey
add esp, 8

push 144 ; 00000090H
push 1
call ?SetKey@@YAXHH@Z ; SetKey
add esp, 8


push 145 ; 00000091H
push 1
call ?SetKey@@YAXHH@Z ; SetKey
add esp, 8

mov DWORD PTR _i$62690[ebp], 0
jmp SHORT $LN6@main
$LN5@main:
mov eax, DWORD PTR _i$62690[ebp]
add eax, 1
mov DWORD PTR _i$62690[ebp], eax
$LN6@main:
cmp DWORD PTR _i$62690[ebp], 99999999 ; 05f5e0ffH
jge SHORT $LN4@main
jmp SHORT $LN5@main
$LN4@main:

push 20 ; 00000014H
push 0
call ?SetKey@@YAXHH@Z ; SetKey
add esp, 8

push 144 ; 00000090H
push 0
call ?SetKey@@YAXHH@Z ; SetKey
add esp, 8

push 145 ; 00000091H
push 0
call ?SetKey@@YAXHH@Z ; SetKey
add esp, 8

mov DWORD PTR _i$62694[ebp], 0
jmp SHORT $LN3@main
$LN2@main:
mov eax, DWORD PTR _i$62694[ebp]
add eax, 1
mov DWORD PTR _i$62694[ebp], eax
$LN3@main:
cmp DWORD PTR _i$62694[ebp], 99999999 ; 05f5e0ffH
jge SHORT $LN1@main
jmp SHORT $LN2@main
$LN1@main:


jmp $LN8@main
$LN7@main:

xor eax, eax

pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END



i use masm 6.14 and use the following commands to compile the source code :
ml asmcode.asm /c /coff
link /SUBSYSTEM:WINDOWS /LIBPATH:c:\masm32\lib asmcode.obj
thanks in advance

Eri523
May 27th, 2011, 08:07 AM
Here's a version I wrote in inline assembly:


void SetKey( BOOL bState,int keyID )
{
BYTE keyState[256];

/*
GetKeyboardState((LPBYTE)&keyState);

if( (bState && !(keyState[keyID] & 1)) || (!bState && (keyState[keyID] & 1)) )
{
keybd_event( keyID,0x45,KEYEVENTF_EXTENDEDKEY | 0,0 );
// Simulate a key release
keybd_event( keyID,0x45,KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,0);
}
*/

__asm {
lea eax, keyState
push eax // Note: This pushes a pointer to keyState
call dword ptr [GetKeyboardState]

cmp bState, 0
je cont001
mov ebx, keyID
test keyState[ebx], 1
je cont002
jmp skip001
cont001: // bState can safely be assumed to be false at this point
mov ebx, keyID
test keyState[ebx], 1
je skip001
cont002:

push 0
push KEYEVENTF_EXTENDEDKEY // | 0
push 45H
push keyID
call dword ptr [keybd_event]

push 0
push KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP
push 45H
push keyID
call dword ptr [keybd_event]

skip001:
}
}


I hope you can adapt it to your requirements. In case of difficulties I'm willing to assist of course. :)

There is, BTW, some room for optimization in the translation of the if condition: If you assume that the C++ implementation you use always represents the bool value true as a number that has the least significant bit set, the whole condition boils down to a mere bit-wise XOR. This is far beyond the demands of the C++ standard but I think it's common in concrete implementations.

Of course the XOR approach can even be used while perfectly respecting the C++ standard, but then there needs to be some conversion applied to the bool operand which may outweigh the gain of that approach.

In general, I don't see a point in trying to remove the compiler/runtime overhead from C++ compiled code. This usually is much more effort than writing it in assembly language in the first place (maybe taking C++ compiled code as a model or inspiration).


for(int i = 0; i < 99999999;i++);


:eek: You don't mean that seriously, do you? Please not that creepy busy-waiting! :thumbd: Windows has such a beautiful Sleep() (http://msdn.microsoft.com/en-us/library/ms686298(VS.85).aspx) function for that... Looks like you compiled the code without optimization only, otherwise I would've assumed that the compiler optimized that away anyway.


mov al, BYTE[ State + VK_CONTROL ]
and al, 1
test al, al
je PASSED


BTW, this is redundant. The sole purpose of the TEST instruction is to perform an AND operation and set the flags accordingly, but to discard the result. OTOH the AND instruction sets the flags as well (while keeping the result). So in this case you can either omit the TEST instruction or omit the AND and change the TEST to TEST AL, 1. Besides, you even can apply the TEST directly to a memory location so the whole thing would boil down to:


test BYTE[ State + VK_CONTROL ], 1
je PASSED


Ok, I admit: I'm counting nanoseconds again... :rolleyes:

Master.
May 27th, 2011, 10:07 AM
Here's a version I wrote in inline assembly:


void SetKey( BOOL bState,int keyID )
{
BYTE keyState[256];

/*
GetKeyboardState((LPBYTE)&keyState);

if( (bState && !(keyState[keyID] & 1)) || (!bState && (keyState[keyID] & 1)) )
{
keybd_event( keyID,0x45,KEYEVENTF_EXTENDEDKEY | 0,0 );
// Simulate a key release
keybd_event( keyID,0x45,KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,0);
}
*/

__asm {
lea eax, keyState
push eax // Note: This pushes a pointer to keyState
call dword ptr [GetKeyboardState]

cmp bState, 0
je cont001
mov ebx, keyID
test keyState[ebx], 1
je cont002
jmp skip001
cont001: // bState can safely be assumed to be false at this point
mov ebx, keyID
test keyState[ebx], 1
je skip001
cont002:

push 0
push KEYEVENTF_EXTENDEDKEY // | 0
push 45H
push keyID
call dword ptr [keybd_event]

push 0
push KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP
push 45H
push keyID
call dword ptr [keybd_event]

skip001:
}
}
I hope you can adapt it to your requirements. In case of difficulties I'm willing to assist of course. :)

There is, BTW, some room for optimization in the translation of the if condition: If you assume that the C++ implementation you use always represents the bool value true as a number that has the least significant bit set, the whole condition boils down to a mere bit-wise XOR. This is far beyond the demands of the C++ standard but I think it's common in concrete implementations.

Of course the XOR approach can even be used while perfectly respecting the C++ standard, but then there needs to be some conversion applied to the bool operand which may outweigh the gain of that approach.

In general, I don't see a point in trying to remove the compiler/runtime overhead from C++ compiled code. This usually is much more effort than writing it in assembly language in the first place (maybe taking C++ compiled code as a model or inspiration).



:eek: You don't mean that seriously, do you? Please not that creepy busy-waiting! :thumbd: Windows has such a beautiful Sleep() (http://msdn.microsoft.com/en-us/library/ms686298%28VS.85%29.aspx) function for that... Looks like you compiled the code without optimization only, otherwise I would've assumed that the compiler optimized that away anyway.



BTW, this is redundant. The sole purpose of the TEST instruction is to perform an AND operation and set the flags accordingly, but to discard the result. OTOH the AND instruction sets the flags as well (while keeping the result). So in this case you can either omit the TEST instruction or omit the AND and change the TEST to TEST AL, 1. Besides, you even can apply the TEST directly to a memory location so the whole thing would boil down to:


test BYTE[ State + VK_CONTROL ], 1
je PASSED
Ok, I admit: I'm counting nanoseconds again... :rolleyes:
thanks a billion dear Eri523 :)
i used that sleep() method you mentioned in my c++ code earlier , but in order to reduce the size of generated codes in asm i removed it and used a simple for statement to simulate a delay :)

and about your code , its just fine , but it seems i cant concentrate well :( cant use this , i'd be grateful if you can help me get the existing code to compile and link :) , leave all of those unnecessary codes alone , i just need some thing to work so that i can assure myself things are going on well, and then it comes the optimization phase and remove the unnecessary codes :)
can you assist me on this too?
(again thank you so much take care :) )

-------------------
and the errors i get :
im gertting three errors at linking stage :
unresolved external symbol __imp__keybd_event@16
unresolved external symbol __imp__GetKeyboardState@4
unresolved external symbol _WinMainCRTStartup

how to overcome these?

Eri523
May 27th, 2011, 12:48 PM
thanks a billion dear Eri523 :)
i used that sleep() method you mentioned in my c++ code earlier , but in order to reduce the size of generated codes in asm i removed it and used a simple for statement to simulate a delay :)

:confused: In an optimized build the call to Sleep() will be compiled into 11 bytes (one PUSH immediate, one indirect CALL) worst case. In my concrete build it could be optimized down to 7 bytes by holding the address of the Sleep() function for the two calls to it in a register. Sleep() is a Windows API function, so no additional runtime stuff is linked for it. And since you're already using Windows API functions anyway, there's no additional overhead for dynamically linking them either.

OTOH your loop compiles into 10 bytes (given I hand-counted that correctly in your assembly listing in post #5). Not that much a gain to justify intentionally using such a bad style...

and about your code , its just fine , but it seems i cant concentrate well :( cant use this , i'd be grateful if you can help me get the existing code to compile and link :) , leave all of those unnecessary codes alone , i just need some thing to work so that i can assure myself things are going on well, and then it comes the optimization phase and remove the unnecessary codes :)
can you assist me on this too?

I'm not really sure I get you here. However, of course I can assist. :) Just try to achieve what's your goal and in case of problems post here, preferably with code (unless it has already been posted here or is really similar to something that has). Maybe we can already get ahead a bit with the following...

-------------------
and the errors i get :
im gertting three errors at linking stage :
unresolved external symbol __imp__keybd_event@16
unresolved external symbol __imp__GetKeyboardState@4
unresolved external symbol _WinMainCRTStartup

how to overcome these?

The first two seem to indicate that user32.lib is missing from your link dependencies.

I'm not sure about the third one though. It obviously has something to do with the C++ runtime, but I don't see anything runtime-related in my linker dependencies. As a wild guess: I could imagine something's wrong with the linker's SubSystem setting.

For reference, here are the dependencies I have in my project:

kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib

You must already have been able to compile your code from post #5. What's different now? I just copy-pasted your code from post #5 into an empty Win32 console project and replaced the C++ version of SetKey() by the one written in inline assembly which I then copy-pasted to the forum. I didn't touch the project properties at all and everything worked fine.

Master.
May 27th, 2011, 01:11 PM
about the Sleep() you are right , i made a mistake. that RTC stuff made me think that those are generated out of that Sleep()!!! so i removed them , it was after that which i found out it doesnt has anything to do with Sleep(), but i left it intact for good :D
anyway i learned sth again and thats good :) thanks again
and about the linking stuff , i need to compile the source code with masm ! .
pure windows assembly you know . so cant use those inline assembly in a c++ project.
i added user32.lib and it compiles just fine . but at linking stage it seems the linker cant find the needed libs !! (user32.inc ) and thats why its generating such errors !
how can i solve that ?
(could you compile the source using masm and link it successfully yourself ? )

Master.
May 27th, 2011, 01:28 PM
and by the way i'll appreciate if you help me on this one too :
actually because i was'nt successful at this little app , i was made to have the windows version coded!! so basically if the problem with the following code gets solved im done :)

the following code will toggle the capslock , numlock and scrolllock LED on keyboard .
it is asked to make it so that everything be automatic ( just a loop that keeps them toggling for eternity! )
to actually have a working code , i need to simulate a keypress , the following interrupt for simulating a keypress wont work! it seems it only works on AT computers .
any help on making it compatible for PC ? (want to run it on a dos os (free dos for example on vmware )

code :

CODESEG SEGMENT
ASSUME CS:CODESEG, DS:CODESEG, ES:CODESEG
ORG 100H
START:
MOV AX,0040H
MOV ES,AX
MOV AL,ES:[0017H]
OR AL,01110000B ; SET CAPSLOCK ON
MOV ES:[0017H],AL

;######################################## simulating a keypress
MOV AH,05H
MOV CH,1EH ; ASCII
MOV CL,61H ; SCAN CODE
INT 16H
;######################################

MOV CX,0FH
LOOP1:
LOOP LOOP1

MOV AX,0040H
MOV ES,AX
MOV AL,ES:[0017H]
AND AL,10001111B
MOV ES:[0017H],AL

;######################################
MOV AH,05H
MOV CH,1EH ; ASCII
MOV CL,61H ; SCAN CODE
INT 16H
;######################################

MOV CX,0FH
LOOP2:
LOOP LOOP2

JMP START

CODESEG ENDS
END START

Eri523
May 27th, 2011, 04:43 PM
and about the linking stuff , i need to compile the source code with masm ! .
pure windows assembly you know . so cant use those inline assembly in a c++ project.
i added user32.lib and it compiles just fine . but at linking stage it seems the linker cant find the needed libs !! (user32.inc ) and thats why its generating such errors !
how can i solve that ?
(could you compile the source using masm and link it successfully yourself ? )

Sorry, I don't have the separate MASM package installed on my system at the moment. (VC++ installs an ml.exe but it seems to be lacking all those header files and maybe libraries to build stand-alone assembly language programs.) Also, I want to leave some of the work to you, you know? ;)

My inline assembly code should be able to run in a stand-alone pure assembly language Windows console program framework with little or no changes required. I suggest you set up such a program and post back in case of difficulties. I'd also suggest to find an alternative for the endless loop in your main() from post #5. I think it'd be really tideous to always force-shut-down the entire console process it is running in everytime you want to stop the program.

IIRC the .inc files for MASM are the equivylent of the C/C++ .h files, so they're for compiling, not for linking. In case you don't have a user32.inc I suggest to try windows.inc, and I'm somehow certain there is one somewhere.

the following code will toggle the capslock , numlock and scrolllock LED on keyboard .
it is asked to make it so that everything be automatic ( just a loop that keeps them toggling for eternity! )
to actually have a working code , i need to simulate a keypress , the following interrupt for simulating a keypress wont work! it seems it only works on AT computers .
any help on making it compatible for PC ? (want to run it on a dos os (free dos for example on vmware )

I don't think AT compatibility is the problem here; AFAIK any of today's Windows PCs (I'n not sure about Macs) should still be AT compatible.

I'm not even sure your code really doesn't work: Maybe it does work and you just don't notice it. Do you really think an empty loop doing 15 iteration would cause any noticable delay? ;) (And I think it actually wouldn't have on probably any computer from at least the last, say, thee decades.) Probably even a loop doing 64k iterations, which is the maximum achievable with the construct you're using in a 16-bit program, wouldn't do on a modern PC.

I'm not even going to complain about the busy-waiting here, since there is no such thing as a sleep function in the BIOS. :rolleyes: However, I would recommend you write your own sleep function because the trivial loop construct you're using now doesn't suffice for the reasons I pointed out above. This would then encapsulate the more complex sleeping stuff. I'd like to suggest something based on the system tick counter (memory address 0000:046C according to http://wiki.osdev.org/Memory_Map_%28x86%29#BIOS_Data_Area_.28BDA.29). It would still be busy-waiting but much more controlable than the bare counting loop approach.

Master.
June 7th, 2011, 08:39 AM
Thanks Eri523 :)
but to my surprise that piece of code never worked in a PC ! i tested it on 3 PCs and it didnt work.
somehow i could come up with another solution for simulating a keypress .
using the Keyboard Controller i could finally do it in DOS :D , and thus made myself free of that Windows asm stuff for now :D
here is the code which works just fine in toggling capslock , numlock and scrolllock:

;in the name of God
;Dos Assembly Code to Toggle Capslock , Numlock and Scrollluck automatically
;Master.huricane@gmail.com
;S.Hossein HasanPour

CODESEG SEGMENT
ASSUME CS:CODESEG, DS:CODESEG, ES:CODESEG
ORG 100H

FAKESCANCODEBYTE:
CALL KBCWAITWRITE
MOV AL,0D2H
OUT 64H,AL
CALL KBCWAITWRITE
MOV AL,BL
OUT 60H,AL
RET

KBCWAITWRITE:
IN AL,64H
TEST AL,00000010B
JNZ KBCWAITWRITE
RET

START:
MOV AX,0040H
MOV ES,AX
MOV AL,ES:[0017H]
OR AL,01110000B ; SET CAPSLOCK ON
MOV ES:[0017H],AL

;*************************************** Method 4 : simulating a keypress
CALL FAKESCANCODEBYTE
;***************************************

MOV CX,0FFFFH
LOOP1:MOV DX,0FFFH
LOOP2:
DEC DX
JNZ LOOP2
LOOP LOOP1


MOV AX,0040H
MOV ES,AX
MOV AL,ES:[0017H]
AND AL,10001111B
MOV ES:[0017H],AL;turnning off keys

;*************************************** Methoid 4 : simulating a keypress
CALL FAKESCANCODEBYTE
;***************************************

MOV CX,0FFFFH
LOOP3:MOV DX,0FFFH
LOOP4:
DEC DX
JNZ LOOP4
LOOP LOOP3

JMP START

CODESEG ENDS
END START

Eri523
June 7th, 2011, 12:16 PM
Wow, I haven't seen this kind of code (the one that works) for a long time... :D

Fine that you've got it working. :thumb: