473,398 Members | 2,368 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,398 software developers and data experts.

Can't Convert BYTE to WORD?

I have two variables: "char A" and "short B". I can be able to convert
from A to B using explicit case conversion with no problem like "B = short
(A);". Right now, I have two variables: "char T[6]" and "short A". T has
an array of six elements. I desire to capture first element and second
element as two bytes into word as short.
The problem is that "A" captures only one element instead of two
elements. I have looked at machine language and I discovered that C++
Compiler selects the wrong instruction which it uses MOV EAX, BYTE PTR [T]
instead of MOV EAX, WORD PTR [T].
Is there a way how I can fix an error in my source code using explicit
case conversion? I tried to use dynamic_cast<>, but it has the same result.
Here is my example code below.

Bryan Parkoff

int main(void)
{
unsigned char T[6] = { "Bryan" }; // I chose unsigned char for string
instead of char.
unsigned short A;

A = unsigned short (*T); // Should capture "Br"

return 0;
}
Jul 23 '05 #1
13 7851
Bryan Parkoff wrote:
I have two variables: "char A" and "short B". I can be able to convert
from A to B using explicit case conversion with no problem like "B = short
(A);".
Actually, AFAIK, there is no need to be explicit. Implicit conversion
should work just fine:

B = A;
Right now, I have two variables: "char T[6]" and "short A". T has
an array of six elements. I desire to capture first element and second
element as two bytes into word as short.
The problem is that "A" captures only one element instead of two
elements. I have looked at machine language and I discovered that C++
Compiler selects the wrong instruction which it uses MOV EAX, BYTE PTR [T]
instead of MOV EAX, WORD PTR [T].
Is there a way how I can fix an error in my source code using explicit
case conversion?
No, you need an arithmetic (or bit manipulation) expression.
I tried to use dynamic_cast<>, but it has the same result.
Here is my example code below.

Bryan Parkoff

int main(void)
{
unsigned char T[6] = { "Bryan" }; // I chose unsigned char for string
instead of char.
unsigned short A;

A = unsigned short (*T); // Should capture "Br"
Why should it? You say here, essentially,

A = unsigned short(T[0]);

so it does as you ask, only takes the first one. You should do something
like

A = (T[0] << CHAR_BIT) | T[1];

(or vice versa depending on where in A you want the 'B' and where the 'r')

return 0;
}


V
Jul 23 '05 #2
Bryan Parkoff wrote:
I have two variables: "char A" and "short B". I can be able to convert
from A to B using explicit case conversion with no problem like "B = short
(A);". Right now, I have two variables: "char T[6]" and "short A". T has
an array of six elements. I desire to capture first element and second
element as two bytes into word as short.
The problem is that "A" captures only one element instead of two
elements. I have looked at machine language and I discovered that C++
Compiler selects the wrong instruction which it uses MOV EAX, BYTE PTR [T]
instead of MOV EAX, WORD PTR [T].
Is there a way how I can fix an error in my source code using explicit
case conversion? I tried to use dynamic_cast<>, but it has the same result.
Here is my example code below.

Bryan Parkoff

int main(void)
{
unsigned char T[6] = { "Bryan" }; // I chose unsigned char for string
instead of char.
unsigned short A;

A = unsigned short (*T); // Should capture "Br"

return 0;
}


*T is an unsigned char, so you have the equivalent of:
unsigned char C = 'B';
unsigned short A = unsigned short(C);

Why would you expect anything else?
Jul 23 '05 #3


Bryan Parkoff wrote:
I have two variables: "char A" and "short B". I can be able to convert
from A to B using explicit case conversion with no problem like "B = short
(A);". Right now, I have two variables: "char T[6]" and "short A". T has
an array of six elements. I desire to capture first element and second
element as two bytes into word as short.
The problem is that "A" captures only one element instead of two
elements. I have looked at machine language and I discovered that C++
Compiler selects the wrong instruction which it uses MOV EAX, BYTE PTR [T]
instead of MOV EAX, WORD PTR [T].
Is there a way how I can fix an error in my source code using explicit
case conversion? I tried to use dynamic_cast<>, but it has the same result.
Here is my example code below.

Bryan Parkoff

int main(void)
{
unsigned char T[6] = { "Bryan" }; // I chose unsigned char for string
instead of char.
unsigned short A;

A = unsigned short (*T); // Should capture "Br"

return 0;
}

Seems like you are thinking that what you have will start copying at
the pointer value into the short. It doesn't.

If you did want to do that, you could use memcpy().
memcpy (&A, T, 2);
However, you have to be sure that's the byte order you want and all
that.

It would be helpful if you explained exactly what you are trying to do,
as copying two characters into a short isn't all that typical of an
operation.

Brian

Jul 23 '05 #4

"Default User" <de***********@yahoo.com> wrote in message
news:11**********************@g49g2000cwa.googlegr oups.com...


Bryan Parkoff wrote:
I have two variables: "char A" and "short B". I can be able to convert
from A to B using explicit case conversion with no problem like "B =
short
(A);". Right now, I have two variables: "char T[6]" and "short A". T
has
an array of six elements. I desire to capture first element and second
element as two bytes into word as short.
The problem is that "A" captures only one element instead of two
elements. I have looked at machine language and I discovered that C++
Compiler selects the wrong instruction which it uses MOV EAX, BYTE PTR
[T]
instead of MOV EAX, WORD PTR [T].
Is there a way how I can fix an error in my source code using
explicit
case conversion? I tried to use dynamic_cast<>, but it has the same
result.
Here is my example code below.

Bryan Parkoff

int main(void)
{
unsigned char T[6] = { "Bryan" }; // I chose unsigned char for string
instead of char.
unsigned short A;

A = unsigned short (*T); // Should capture "Br"

return 0;
}

Seems like you are thinking that what you have will start copying at
the pointer value into the short. It doesn't.

If you did want to do that, you could use memcpy().
memcpy (&A, T, 2);
However, you have to be sure that's the byte order you want and all
that.

It would be helpful if you explained exactly what you are trying to do,
as copying two characters into a short isn't all that typical of an
operation.

Brian,

Thank you for the information. I am sure that memcpy() works, but I
want to use two x86 instruction that uses WORD instead of BYTE, but C++
Compiler only assigns BYTE instead of WORD. It is the way how C++ Compiler
works. I don't know if there is no solution so I am forced to use __asm
function. I do not wish to use left shift to move first byte to the left
before use "or" to capture second byte so two bytes becomes word. SHIFT and
ROTATE are hurt on Intel Pentium 4 because of eating about 7 clock cycles
rather than one clock cycle.
Variable: T is defined in BYTE ARRAY, but I force to tell C++ Compiler
to capture two bytes from BYTE ARRAY. Please look at my C++ source code
with my comment below.

// Example 1
int main(void)
{
unsigned char T[6] = { "Bryan" }; // I chose unsigned char for string
instead of char.
unsigned short A; // C++ Compiler assigns "movzx EAX, BYTE PTR [T]"
because T is defined as BYTE ARRAY.

A = unsigned short (*T); // Should capture "Br"

return 0;
}

// Example 2
int main(void)
{
unsigned char T[6] = { "Bryan" }; // I chose unsigned char for string
instead of char.
unsigned short A; // C++ Compiler assigns "movzx EAX, BYTE PTR [T]"
because T is defined as BYTE ARRAY.

// A = unsigned short (*T); // Should capture "Br"
__asm
{
movzx EAX, WORD PTR [T] // Remove "movzx EAX, BYTE PTR [T]" from C++
Compiler
mov WORD PTR [A], AX
}

return 0;
}

Bryan Parkoff
Jul 23 '05 #5
Bryan Parkoff wrote:
[redacted]


1. How a specific compiler generates cod is OT.
2. 80x86 ASM is OT (the __asm keyword)
3. To do what you want, you need to drop into the realm of UB
(specifically, cast &T[0] to an unsigned short *, and dererence that.
4. What, specifically, are you attempting to do, where memcpy() would be
insufficient (whereas it is defined behavior and portable, save for
endian issues)?
Jul 23 '05 #6
"Bryan Parkoff" <no****@nospam.com> wrote in message news:w8**************@newssvr30.news.prodigy.com.. .

A = *((unsigned short *)T);

Todd

Jul 23 '05 #7
"Todd Brylski" <tb******@yyaahhoooo.com> wrote in message
news:yr*******************@tornado.rdc-kc.rr.com...
"Bryan Parkoff" <no****@nospam.com> wrote in message
news:w8**************@newssvr30.news.prodigy.com.. .

A = *((unsigned short *)T);

Todd,

You got the right answer. Thank you very much. It helps me a lot to
save performance.

Bryan Parkoff
Jul 23 '05 #8
Bryan Parkoff wrote:
"Todd Brylski":
"Bryan Parkoff" <no****@nospam.com> wrote:

A = *((unsigned short *)T);

Note that those brackets are unnecessary:
A = *(unsigned short *)T;
You got the right answer. Thank you very much. It helps me a
lot to save performance.


I guess that depends what you mean by 'performance'. This code
is non-portable, eg. it may crash the program on Sun hardware.

Try this one:
memcpy(&A, T, sizeof A);

Jul 23 '05 #9
Bryan Parkoff wrote:

int main(void)
{
unsigned char T[6] = { "Bryan" }; // I chose unsigned char for string
instead of char.
unsigned short A;

A = unsigned short (*T); // Should capture "Br"

return 0;
}


I think what you're looking for might have been:

A = *((unsigned short *)T);

But this is naughty as it assumes that sizeof(short) == 2, and that your
machine architecture is little-endian.

--
Mike Smith
Jul 23 '05 #10
"Old Wolf" <ol*****@inspire.net.nz> wrote in message
news:11**********************@o13g2000cwo.googlegr oups.com...
Bryan Parkoff wrote:
"Todd Brylski":
> "Bryan Parkoff" <no****@nospam.com> wrote:
>
> A = *((unsigned short *)T);


Note that those brackets are unnecessary:
A = *(unsigned short *)T;
You got the right answer. Thank you very much. It helps me a
lot to save performance.


I guess that depends what you mean by 'performance'. This code
is non-portable, eg. it may crash the program on Sun hardware.

Try this one:
memcpy(&A, T, sizeof A);

Well, I ran this loop over 0x10000000 times to use left shift and "or"
before it takes 400 ms on Pentium III, but it use WORD pointer instead of
left shift and "or" before it takes 370 ms.
I doubt that it may crash on other non-x86 machine unless little endian
and big endian are defined. I don't accept memcpy() function because it
takes too many cycles that can degrade performance however WORD pointer uses
only two x86 instructions.
I will try to test on other non-x86 machine later.

Bryan Parkoff
Jul 23 '05 #11
Bryan Parkoff wrote:
"Old Wolf" <ol*****@inspire.net.nz> wrote:

A = *(unsigned short *)T;

This code is non-portable, eg. it may crash the program on Sun hardware.


I doubt that it may crash on other non-x86 machine


On some machines, the program crashes if you try to read a short
out of an odd-numbered memory location. This is called "alignment".
Sun hardware is one such platform.

Of course, you might be lucky and end up with T being an even-
numbered address.

Jul 23 '05 #12
Bryan Parkoff wrote:
You got the right answer. Thank you very much. It helps me a
lot to save performance.
I guess that depends what you mean by 'performance'. This code
is non-portable, eg. it may crash the program on Sun hardware.

Try this one:
memcpy(&A, T, sizeof A);

Well, I ran this loop over 0x10000000 times to use left shift and "or"
before it takes 400 ms on Pentium III, but it use WORD pointer instead of
left shift and "or" before it takes 370 ms.


So? This seems like a negligible difference to me, considering that your
final program is likely to do other things that just copying char values
into short variables, I'd be surprised if there is any noticable difference
at all.
I doubt that it may crash on other non-x86 machine unless little
endian and big endian are defined.
You doubt it, but you don't know why it might crash, do you?
I don't accept memcpy() function because it takes too many cycles that
can degrade performance
It does? That's strange. On my compiler, memcpy is extremely fast. How big
is the difference on your system?
however WORD pointer uses only two x86 instructions.
My compiler transforms the memcpy call into two assembler instructions on
x86.
I will try to test on other non-x86 machine later.

Jul 23 '05 #13


Bryan Parkoff wrote:
"Default User" <de***********@yahoo.com> wrote in message
news:11**********************@g49g2000cwa.googlegr oups.com...
Seems like you are thinking that what you have will start copying at
the pointer value into the short. It doesn't.

If you did want to do that, you could use memcpy().
memcpy (&A, T, 2);
However, you have to be sure that's the byte order you want and all
that.


Thank you for the information. I am sure that memcpy() works, but I
want to use two x86 instruction that uses WORD instead of BYTE, but C++
Compiler only assigns BYTE instead of WORD. It is the way how C++ Compiler
works. I don't know if there is no solution so I am forced to use __asm
function. I do not wish to use left shift to move first byte to the left
before use "or" to capture second byte so two bytes becomes word. SHIFT and
ROTATE are hurt on Intel Pentium 4 because of eating about 7 clock cycles
rather than one clock cycle.


It seems to me that you are deep in premature-optimization land. Your
"test" that you mention in another post is far from conclusive.

You should use the construct that is clearest and most portable until
such time as you have a demonstrated (not just desired) need for
something else.

Library routines such as memcpy() are usually highly optimized for an
implementation. Invoking undefined behavior with a substitute while
chasing a (possibly illusory) performance advantage is a fool's gambit.

It is possible to switch the problem around safely, that is to cast the
short* to a char* and stuff the two bytes that way. I doubt it's of
much advantage, nor will it likely give you that particular assembly
instruction set you seem to crave.

At any rate, you are rapidly heading off into waters that are off-topic
for this newsgroup.

Brian

Jul 23 '05 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

19
by: Vincent | last post by:
Hi all, I want to convert a char (binary) to an unsigned long. How can I do this? Thanks, Vincent
0
by: windandwaves | last post by:
Hi folk Create two tables: 1. SOURCE 2. SOURCE_CONVERSION give them two fields: 1. ID = autonumber primary key
10
by: Kristian Nybo | last post by:
Hi, I'm writing a simple image file exporter as part of a school project, and I would like to write completely platform-independent code if at all possible. The problem I've run into is that...
2
by: Christopher Beltran | last post by:
I am currently trying to replace certain strings, not single characters, with other strings inside a word document which is then sent to a browser as a binary file. Right now, I read in the word...
2
by: Mel Weaver | last post by:
Hello, I'm trying to convert these to functions to c# const C1 = 52845; C2 = 22719; function Encrypt(const S: String; Key: Word): String; var I: byte;
9
by: charliewest | last post by:
Hello - I have images saved in my SQL SERVER 2000 database. Using ASP.NET (C#) is there any way to temporarily save an image to a session object, and after running some other operations, later...
14
by: Charles Law | last post by:
I thought this had come up before, but I now cannot find it. I have a byte array, such as Dim a() As Byte = {1, 2, 3, 4} I want to convert this to an Int32 = 01020304 (hex). If I use...
5
by: Bob Homes | last post by:
In VB6, foreground and background colors of controls had to be assigned a single number. If you knew the RGB values for the color, you still had to convert them into the single number accepatable...
4
by: Franky | last post by:
I have a Command Prompt window open and select all the characters and copy them to the clipboard. I then read them from the clipboard str = CType(DataO.GetData(DataFormats.OemText, False),...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.