Testing how the DCB structure translates to assembler. This snippet compiles fine with M$ C compiler:#include <windows.h>
#include <conio.h>
int main(int argc, char* argv[]) {
DCB dcb={sizeof(DCB), 0x12345678, 0, FALSE, RTS_CONTROL_HANDSHAKE,FALSE,FALSE, FALSE,FALSE,FALSE,FALSE,DTR_CONTROL_HANDSHAKE,TRUE,TRUE,NULL,TRUE};
// _asm int 3;
_asm lea eax, dcb; //1c 00 00 00, 78 56 34 12, 00 98 00 00
_asm lea edx, dcb.BaudRate;
_asm lea ecx, dcb.BaudRate[4];
_asm mov eax, [ecx];
dcb.fBinary=1;
// 00DC7E4A ³. 8B45 E8 mov eax, [ebp-18]
// 00DC7E4D ³. 83E0 CF and eax, FFFFFFCF
// 00DC7E50 ³. 83C8 20 or eax, 00000020
// 00DC7E53 ³. 8945 E8 mov [ebp-18], eax
printf("ok");
_getch(); // for use with console
}
sizeof(DCB) is 1Ch, 28 bytes, of which the BITRECORD is only 4 bytes, of course.
The 0x12345678 is the baudrate, nonsense obviously but it helps to find its location in Olly's memory dump.
So 00 98 00 00 -> 9800h is the expected result for the values discussed in Serial I/O communications (terminal) code (http://masm32.com/board/index.php?topic=6288.0)
WinBase.h:typedef struct _DCB {
DWORD DCBlength; /* sizeof(DCB) */
DWORD BaudRate; /* Baudrate at which running */
DWORD fBinary: 1; /* Binary Mode (skip EOF check) */
DWORD fParity: 1; /* Enable parity checking */
DWORD fOutxCtsFlow:1; /* CTS handshaking on output */
DWORD fOutxDsrFlow:1; /* DSR handshaking on output */
DWORD fDtrControl:2; /* DTR Flow control */
DWORD fDsrSensitivity:1; /* DSR Sensitivity */
DWORD fTXContinueOnXoff: 1; /* Continue TX when Xoff sent */
DWORD fOutX: 1; /* Enable output X-ON/X-OFF */
DWORD fInX: 1; /* Enable input X-ON/X-OFF */
DWORD fErrorChar: 1; /* Enable Err Replacement */
DWORD fNull: 1; /* Enable Null stripping */
DWORD fRtsControl:2; /* Rts Flow control */
DWORD fAbortOnError:1; /* Abort all reads and writes on Error */
DWORD fDummy2:17; /* Reserved */
WORD wReserved; /* Not currently used */
WORD XonLim; /* Transmit X-ON threshold */
WORD XoffLim; /* Transmit X-OFF threshold */
BYTE ByteSize; /* Number of bits/byte, 4-8 */
BYTE Parity; /* 0-4=None,Odd,Even,Mark,Space */
BYTE StopBits; /* 0,1,2 = 1, 1.5, 2 */
char XonChar; /* Tx and Rx X-ON character */
char XoffChar; /* Tx and Rx X-OFF character */
char ErrorChar; /* Error replacement char */
char EofChar; /* End of Input character */
char EvtChar; /* Received Event character */
WORD wReserved1; /* Fill for now. */
} DCB, *LPDCB;
P.S.: If you need a simple C replacement for Print Bin$(eax) (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1199), see Is there a printf converter to print in binary format? (https://stackoverflow.com/questions/111928/is-there-a-printf-converter-to-print-in-binary-format) ;)
Another test#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <conio.h>
//DCB dcb={sizeof(DCB), 0x12345678, 0, FALSE, RTS_CONTROL_HANDSHAKE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,DTR_CONTROL_HANDSHAKE,TRUE,TRUE,NULL,TRUE};
DCB dcb={sizeof(DCB), 0x12345678, TRUE,FALSE,TRUE,TRUE,DTR_CONTROL_HANDSHAKE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,RTS_CONTROL_HANDSHAKE,FALSE,0};
int main(void)
{
char abits[33];
DWORD bm;
dcb.fBinary = 1;
bm = *((DWORD*)&dcb+2); // read 3. DWORD where the fBinary is
abits[32] = 0;
for (int i = 0; i < 32; i++)
abits[31 - i] = (bm & 1 << i)?'1':'0';
printf("%04Xh %s\n", bm, abits);
printf("ok");
_getch(); // for use with console
return 0;
}
202Dh 00000000000000000010000000101101
ok
Thanks, Tim - your test showed me the way to go :t
include \masm32\include\masm32rt.inc
include BitRecord.mac
.code
start:
print "00000000000000000010000000101101", 9, "expected, see Tim's code", crlf
print bin$(_Record(TRUE,FALSE,TRUE,TRUE,DTR_CONTROL_HANDSHAKE:2,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,RTS_CONTROL_HANDSHAKE:2,FALSE,0)), crlf
inkey bin$(_RecordRev(0,FALSE,RTS_CONTROL_HANDSHAKE:2,FALSE,FALSE, FALSE,FALSE,FALSE,FALSE,DTR_CONTROL_HANDSHAKE:2,TRUE,TRUE,NULL,TRUE)), crlf
exit
end start
Output:00000000000000000010000000101101 expected, see Tim's code
00000000000000000010000000101101
00000000000000000010000000101101
_Record() uses the same order as the DBC structure, so we might declare that the "natural" order ;-)
There is no data or RECORD to be declared; the macro simply builds a single integer value. All elements represent one bit, except if they have e.g. DTR_CONTROL_HANDSHAKE:2, where :n represents the field's bit length.
Behaviour is the same for all assemblers (ML, UAsm, JWasm, AsmC).
Okay, I put together a prog for testing, and it seem to confirm everything I've been saying.
edit: replace zip. minor cleanup not affecting results.