Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

assembly - How to populate a 64 bit register with duplicate byte values

I'm doing some x64 assembly with Visual C++ 2010 and masm ('fast call' calling convention).

So let's say I have a function in C++:

extern "C" void fillArray(unsigned char* byteArray, unsigned char value);

The pointer to array will be in RCX and char value will be in DL

How can I fill RAX with values using DL such that if I were to mov qword ptr [RCX], RAX and print byteArray, all the values would be equal to 'char value'?

Please note that I'm not trying to do out-code my compiler, I'm just learning.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You can multiply by 0x0101010101010101 to copy the lowest byte into all other bytes (assuming the rest were all zero to begin with), it's slightly annoying because there is no imul r64, r64, imm64 but you can could do this:

mov  rax, 0x0101010101010101 
imul rax, rdx                 ; at least as fast as  mul rdx  on all CPUs

If rdx is not of the required form (in other words, if it has some extra bits set), just add a
movzx eax, dl in front, and move the constant into RDX or another register. (movzx edx,dl can't benefit from mov-elimination on Intel CPUs.)

If you don't like the code size (mov r64, imm64 is already 10 bytes by itself), just stick that constant in your data segment.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

56.6k users

...