1 #include <assert.h>
2 #include <stdexcept>
3 #include "X86Assembler.h"
4 #include "LiteralPool.h"
5 
Begin()6 void CX86Assembler::Begin()
7 {
8 	m_nextLabelId = 1;
9 	m_nextLiteral128Id = 1;
10 	m_currentLabel = nullptr;
11 	m_tmpStream.ResetBuffer();
12 	m_labels.clear();
13 	m_labelOrder.clear();
14 }
15 
End()16 void CX86Assembler::End()
17 {
18 	//Mark last label
19 	if(m_currentLabel != nullptr)
20 	{
21 		uint32 currentPos = static_cast<uint32>(m_tmpStream.Tell());
22 		m_currentLabel->size = currentPos - m_currentLabel->start;
23 	}
24 
25 	//Initialize
26 	for(auto& labelPair : m_labels)
27 	{
28 		auto& label = labelPair.second;
29 		label.projectedStart = label.start;
30 	}
31 
32 	while(1)
33 	{
34 		bool changed = false;
35 
36 		for(LabelArray::const_iterator labelIterator(m_labelOrder.begin());
37 			labelIterator != m_labelOrder.end(); ++labelIterator)
38 		{
39 			auto& label = m_labels[*labelIterator];
40 
41 			for(LabelRefArray::iterator labelRefIterator(label.labelRefs.begin());
42 				labelRefIterator != label.labelRefs.end(); ++labelRefIterator)
43 			{
44 				auto& labelRef(*labelRefIterator);
45 				switch(labelRef.length)
46 				{
47 					case JMP_NOTSET:
48 						{
49 							//Assume a short jump first.
50 							unsigned int jumpSize = GetJumpSize(labelRef.type, JMP_NEAR);
51 							labelRef.length = JMP_NEAR;
52 							IncrementJumpOffsetsLocal(label, labelRefIterator + 1, jumpSize);
53 							IncrementJumpOffsets(labelIterator + 1, jumpSize);
54 							changed = true;
55 						}
56 						break;
57 					case JMP_NEAR:
58 						{
59 							//We need to verify if the jump is still good for us, since sizes might have changed
60 							LABELINFO& referencedLabel(m_labels[labelRef.label]);
61 							unsigned int smallJumpSize = GetJumpSize(labelRef.type, JMP_NEAR);
62 							uint32 offset = referencedLabel.projectedStart - (labelRef.offset + smallJumpSize);
63 							uint32 offsetSize = GetMinimumConstantSize(offset);
64 							if(offsetSize != 1)
65 							{
66 								//Doesn't fit, recompute offsets
67 								labelRef.length = JMP_FAR;
68 								unsigned int longJumpSize = GetJumpSize(labelRef.type, JMP_FAR);
69 								unsigned int incrementAmount = longJumpSize - smallJumpSize;
70 								IncrementJumpOffsetsLocal(label, labelRefIterator + 1, incrementAmount);
71 								IncrementJumpOffsets(labelIterator + 1, incrementAmount);
72 								changed = true;
73 							}
74 						}
75 						break;
76 				}
77 			}
78 		}
79 
80 		if(!changed) break;
81 	}
82 
83 	assert(m_outputStream != nullptr);
84 	m_tmpStream.Seek(0, Framework::STREAM_SEEK_SET);
85 
86 	for(const auto& labelId : m_labelOrder)
87 	{
88 		const auto& label = m_labels[labelId];
89 
90 		unsigned int currentPos = label.start;
91 		unsigned int currentProjectedPos = label.projectedStart;
92 		unsigned int endPos = label.start + label.size;
93 
94 		for(const auto& labelRef : label.labelRefs)
95 		{
96 			const auto& referencedLabel(m_labels[labelRef.label]);
97 
98 			unsigned int readSize = labelRef.offset - currentProjectedPos;
99 			if(readSize != 0)
100 			{
101 				m_copyBuffer.resize(readSize);
102 				m_tmpStream.Read(m_copyBuffer.data(), readSize);
103 				m_outputStream->Write(m_copyBuffer.data(), readSize);
104 			}
105 
106 			//Write our jump here.
107 			unsigned int jumpSize = GetJumpSize(labelRef.type, labelRef.length);
108 			uint32 distance = referencedLabel.projectedStart - (labelRef.offset + jumpSize);
109 			WriteJump(m_outputStream, labelRef.type, labelRef.length, distance);
110 
111 			currentProjectedPos += readSize + jumpSize;
112 			currentPos += readSize;
113 		}
114 
115 		unsigned int lastCopySize = endPos - currentPos;
116 		if(lastCopySize != 0)
117 		{
118 			m_copyBuffer.resize(lastCopySize);
119 			m_tmpStream.Read(m_copyBuffer.data(), lastCopySize);
120 			m_outputStream->Write(m_copyBuffer.data(), lastCopySize);
121 		}
122 	}
123 
124 	ResolveLiteralReferences();
125 }
126 
IncrementJumpOffsets(LabelArray::const_iterator startLabel,unsigned int amount)127 void CX86Assembler::IncrementJumpOffsets(LabelArray::const_iterator startLabel, unsigned int amount)
128 {
129 	for(LabelArray::const_iterator labelIterator(startLabel);
130 		labelIterator != m_labelOrder.end(); ++labelIterator)
131 	{
132 		LABELINFO& label = m_labels[*labelIterator];
133 		label.projectedStart += amount;
134 		IncrementJumpOffsetsLocal(label, label.labelRefs.begin(), amount);
135 	}
136 }
137 
IncrementJumpOffsetsLocal(LABELINFO & label,LabelRefArray::iterator startJump,unsigned int amount)138 void CX86Assembler::IncrementJumpOffsetsLocal(LABELINFO& label, LabelRefArray::iterator startJump, unsigned int amount)
139 {
140 	for(LabelRefArray::iterator labelRefIterator(startJump);
141 		labelRefIterator != label.labelRefs.end(); ++labelRefIterator)
142 	{
143 		auto& labelRef(*labelRefIterator);
144 
145 		//Make sure any literal ref happens before a label ref
146 		for(const auto& literalRefPair : label.literal128Refs)
147 		{
148 			const auto& literalRef = literalRefPair.second;
149 			assert(literalRef.offset < labelRef.offset);
150 		}
151 
152 		labelRef.offset += amount;
153 	}
154 }
155 
SetStream(Framework::CStream * stream)156 void CX86Assembler::SetStream(Framework::CStream* stream)
157 {
158 	m_outputStream = stream;
159 }
160 
MakeRegisterAddress(REGISTER nRegister)161 CX86Assembler::CAddress CX86Assembler::MakeRegisterAddress(REGISTER nRegister)
162 {
163 	CAddress Address;
164 
165 	if(nRegister > 7)
166 	{
167 		Address.nIsExtendedModRM = true;
168 		nRegister = static_cast<REGISTER>(nRegister & 7);
169 	}
170 
171 	Address.ModRm.nMod = 3;
172 	Address.ModRm.nRM = nRegister;
173 
174 	return Address;
175 }
176 
MakeXmmRegisterAddress(XMMREGISTER registerId)177 CX86Assembler::CAddress CX86Assembler::MakeXmmRegisterAddress(XMMREGISTER registerId)
178 {
179 	return MakeRegisterAddress(static_cast<REGISTER>(registerId));
180 }
181 
MakeByteRegisterAddress(BYTEREGISTER registerId)182 CX86Assembler::CAddress CX86Assembler::MakeByteRegisterAddress(BYTEREGISTER registerId)
183 {
184 	auto address = MakeRegisterAddress(static_cast<REGISTER>(registerId));
185 	address.usesLegacyByteRegister = true;
186 	return address;
187 }
188 
MakeIndRegAddress(REGISTER registerId)189 CX86Assembler::CAddress CX86Assembler::MakeIndRegAddress(REGISTER registerId)
190 {
191 	CAddress address;
192 
193 	//Cannot be done with rBP
194 	assert(registerId != rBP);
195 	if(registerId == r13)
196 	{
197 		return MakeIndRegOffAddress(registerId, 0);
198 	}
199 
200 	if(registerId == rSP)
201 	{
202 		registerId = static_cast<REGISTER>(4);
203 		address.sib.scale = 0;
204 		address.sib.index = 4;
205 		address.sib.base = 4;
206 	}
207 	else if(registerId == r12)
208 	{
209 		registerId = static_cast<REGISTER>(4);
210 		address.sib.scale = 0;
211 		address.sib.index = 4;
212 		address.sib.base = 4;
213 		address.nIsExtendedModRM = true;
214 	}
215 
216 	if(registerId > 7)
217 	{
218 		address.nIsExtendedModRM = true;
219 		registerId = static_cast<REGISTER>(registerId & 7);
220 	}
221 
222 	address.ModRm.nMod = 0;
223 	address.ModRm.nRM = registerId;
224 	return address;
225 }
226 
MakeIndRegOffAddress(REGISTER nRegister,uint32 nOffset)227 CX86Assembler::CAddress CX86Assembler::MakeIndRegOffAddress(REGISTER nRegister, uint32 nOffset)
228 {
229 	if(
230 		(nOffset == 0) &&
231 		(nRegister != CX86Assembler::rBP) &&
232 		(nRegister != CX86Assembler::r13)
233 		)
234 	{
235 		return MakeIndRegAddress(nRegister);
236 	}
237 
238 	CAddress Address;
239 
240 	if(nRegister == rSP)
241 	{
242 		nRegister = static_cast<REGISTER>(4);
243 		Address.sib.scale = 0;
244 		Address.sib.index = 4;
245 		Address.sib.base = 4;
246 	}
247 	else if(nRegister == r12)
248 	{
249 		nRegister = static_cast<REGISTER>(4);
250 		Address.nIsExtendedModRM = true;
251 		Address.sib.scale = 0;
252 		Address.sib.index = 4;
253 		Address.sib.base = 4;
254 	}
255 
256 	if(nRegister > 7)
257 	{
258 		Address.nIsExtendedModRM = true;
259 		nRegister = static_cast<REGISTER>(nRegister & 7);
260 	}
261 
262 	if(GetMinimumConstantSize(nOffset) == 1)
263 	{
264 		Address.ModRm.nMod = 1;
265 		Address.nOffset = static_cast<uint8>(nOffset);
266 	}
267 	else
268 	{
269 		Address.ModRm.nMod = 2;
270 		Address.nOffset = nOffset;
271 	}
272 
273 	Address.ModRm.nRM = nRegister;
274 
275 	return Address;
276 }
277 
MakeBaseIndexScaleAddress(REGISTER base,REGISTER index,uint8 scale)278 CX86Assembler::CAddress CX86Assembler::MakeBaseIndexScaleAddress(REGISTER base, REGISTER index, uint8 scale)
279 {
280 	if(base == rBP)
281 	{
282 		throw std::runtime_error("Invalid base.");
283 	}
284 	if(base == r13)
285 	{
286 		return MakeBaseOffIndexScaleAddress(base, 0, index, scale);
287 	}
288 	if(index == rSP)
289 	{
290 		throw std::runtime_error("Invalid index.");
291 	}
292 
293 	CAddress address;
294 	address.ModRm.nRM = 4;
295 
296 	if(base > 7)
297 	{
298 		address.nIsExtendedModRM = true;
299 		base = static_cast<REGISTER>(base & 7);
300 	}
301 	if(index > 7)
302 	{
303 		address.nIsExtendedSib = true;
304 		index = static_cast<REGISTER>(index & 7);
305 	}
306 	address.sib.base = base;
307 	address.sib.index = index;
308 	switch(scale)
309 	{
310 	case 1:
311 		address.sib.scale = 0;
312 		break;
313 	case 2:
314 		address.sib.scale = 1;
315 		break;
316 	case 4:
317 		address.sib.scale = 2;
318 		break;
319 	case 8:
320 		address.sib.scale = 3;
321 		break;
322 	default:
323 		throw std::runtime_error("Invalid scale.");
324 		break;
325 	}
326 
327 	return address;
328 }
329 
MakeBaseOffIndexScaleAddress(REGISTER base,uint32 offset,REGISTER index,uint8 scale)330 CX86Assembler::CAddress CX86Assembler::MakeBaseOffIndexScaleAddress(REGISTER base, uint32 offset, REGISTER index, uint8 scale)
331 {
332 	//This could also be rBP, but untested for now
333 	if(base != r13)
334 	{
335 		throw std::runtime_error("Invalid base.");
336 	}
337 	if(index == rSP)
338 	{
339 		throw std::runtime_error("Invalid index.");
340 	}
341 
342 	CAddress address;
343 	address.ModRm.nRM = 4;
344 
345 	if(base > 7)
346 	{
347 		address.nIsExtendedModRM = true;
348 		base = static_cast<REGISTER>(base & 7);
349 	}
350 	if(index > 7)
351 	{
352 		address.nIsExtendedSib = true;
353 		index = static_cast<REGISTER>(index & 7);
354 	}
355 	address.sib.base = base;
356 	address.sib.index = index;
357 	switch(scale)
358 	{
359 	case 1:
360 		address.sib.scale = 0;
361 		break;
362 	case 2:
363 		address.sib.scale = 1;
364 		break;
365 	case 4:
366 		address.sib.scale = 2;
367 		break;
368 	case 8:
369 		address.sib.scale = 3;
370 		break;
371 	default:
372 		throw std::runtime_error("Invalid scale.");
373 		break;
374 	}
375 
376 	if(GetMinimumConstantSize(offset) == 1)
377 	{
378 		address.ModRm.nMod = 1;
379 		address.nOffset = static_cast<uint8>(offset);
380 	}
381 	else
382 	{
383 		address.ModRm.nMod = 2;
384 		address.nOffset = offset;
385 	}
386 
387 	return address;
388 }
389 
MakeLiteral128Address(LITERAL128ID literalId)390 CX86Assembler::CAddress CX86Assembler::MakeLiteral128Address(LITERAL128ID literalId)
391 {
392 	CAddress address;
393 	address.nOffset = 0;
394 	address.ModRm.nMod = 0;
395 	address.ModRm.nRM = 5;
396 	address.literal128Id = literalId;
397 	return address;
398 }
399 
CreateLabel()400 CX86Assembler::LABEL CX86Assembler::CreateLabel()
401 {
402 	LABEL newLabelId = m_nextLabelId++;
403 	m_labels[newLabelId] = LABELINFO();
404 	return newLabelId;
405 }
406 
MarkLabel(LABEL label,int32 offset)407 void CX86Assembler::MarkLabel(LABEL label, int32 offset)
408 {
409 	uint32 currentPos = static_cast<uint32>(m_tmpStream.Tell()) + offset;
410 
411 	if(m_currentLabel != NULL)
412 	{
413 		m_currentLabel->size = currentPos - m_currentLabel->start;
414 	}
415 
416 	auto labelIterator(m_labels.find(label));
417 	assert(labelIterator != m_labels.end());
418 	auto& labelInfo(labelIterator->second);
419 	labelInfo.start = currentPos;
420 	m_currentLabel = &labelInfo;
421 	m_labelOrder.push_back(label);
422 }
423 
GetLabelOffset(LABEL label) const424 uint32 CX86Assembler::GetLabelOffset(LABEL label) const
425 {
426 	auto labelIterator(m_labels.find(label));
427 	assert(labelIterator != m_labels.end());
428 	const auto& labelInfo(labelIterator->second);
429 	return labelInfo.projectedStart;
430 }
431 
CreateLiteral128(const LITERAL128 & literal)432 CX86Assembler::LITERAL128ID CX86Assembler::CreateLiteral128(const LITERAL128& literal)
433 {
434 	auto literalId = m_nextLiteral128Id++;
435 	LITERAL128REF literalRef;
436 	literalRef.value = literal;
437 	assert(m_currentLabel);
438 	m_currentLabel->literal128Refs.insert(std::make_pair(literalId, literalRef));
439 	return literalId;
440 }
441 
ResolveLiteralReferences()442 void CX86Assembler::ResolveLiteralReferences()
443 {
444 	CLiteralPool literalPool(m_outputStream);
445 	literalPool.AlignPool();
446 
447 	for(const auto& labelId : m_labelOrder)
448 	{
449 		const auto& label = m_labels[labelId];
450 		assert(label.projectedStart >= label.start);
451 		uint32 projectedDiff = label.projectedStart - label.start;
452 		for(const auto& literalRefPair : label.literal128Refs)
453 		{
454 			const auto& literal = literalRefPair.second;
455 			auto literalPos = static_cast<uint32>(literalPool.GetLiteralPosition(literal.value));
456 			uint32 projectedOffset = literal.offset + projectedDiff;
457 			m_outputStream->Seek(projectedOffset, Framework::STREAM_SEEK_SET);
458 			static const uint32 opcodeSize = 4;
459 			auto offset = literalPos - projectedOffset - opcodeSize;
460 			m_outputStream->Write32(offset);
461 		}
462 	}
463 
464 	m_outputStream->Seek(0, Framework::STREAM_SEEK_END);
465 }
466 
AdcEd(REGISTER registerId,const CAddress & address)467 void CX86Assembler::AdcEd(REGISTER registerId, const CAddress& address)
468 {
469 	WriteEvGvOp(0x13, false, address, registerId);
470 }
471 
AdcId(const CAddress & address,uint32 constant)472 void CX86Assembler::AdcId(const CAddress& address, uint32 constant)
473 {
474 	WriteEvId(0x02, address, constant);
475 }
476 
AddEd(REGISTER registerId,const CAddress & address)477 void CX86Assembler::AddEd(REGISTER registerId, const CAddress& address)
478 {
479 	WriteEvGvOp(0x03, false, address, registerId);
480 }
481 
AddEq(REGISTER registerId,const CAddress & address)482 void CX86Assembler::AddEq(REGISTER registerId, const CAddress& address)
483 {
484 	WriteEvGvOp(0x03, true, address, registerId);
485 }
486 
AddId(const CAddress & Address,uint32 nConstant)487 void CX86Assembler::AddId(const CAddress& Address, uint32 nConstant)
488 {
489 	WriteEvId(0x00, Address, nConstant);
490 }
491 
AddIq(const CAddress & address,uint64 constant)492 void CX86Assembler::AddIq(const CAddress& address, uint64 constant)
493 {
494 	WriteEvIq(0x00, address, constant);
495 }
496 
AndEd(REGISTER registerId,const CAddress & address)497 void CX86Assembler::AndEd(REGISTER registerId, const CAddress& address)
498 {
499 	WriteEvGvOp(0x23, false, address, registerId);
500 }
501 
AndEq(REGISTER registerId,const CAddress & address)502 void CX86Assembler::AndEq(REGISTER registerId, const CAddress& address)
503 {
504 	WriteEvGvOp(0x23, true, address, registerId);
505 }
506 
AndIb(const CAddress & address,uint8 constant)507 void CX86Assembler::AndIb(const CAddress& address, uint8 constant)
508 {
509 	assert(!address.NeedsExtendedByteAddress());
510 	WriteEvIb(0x04, address, constant);
511 }
512 
AndId(const CAddress & address,uint32 constant)513 void CX86Assembler::AndId(const CAddress& address, uint32 constant)
514 {
515 	WriteEvId(0x04, address, constant);
516 }
517 
AndIq(const CAddress & address,uint64 constant)518 void CX86Assembler::AndIq(const CAddress& address, uint64 constant)
519 {
520 	assert(0);
521 }
522 
BsrEd(REGISTER registerId,const CAddress & address)523 void CX86Assembler::BsrEd(REGISTER registerId, const CAddress& address)
524 {
525 	WriteEvGvOp0F(0xBD, false, address, registerId);
526 }
527 
CallEd(const CAddress & address)528 void CX86Assembler::CallEd(const CAddress& address)
529 {
530 	WriteEvOp(0xFF, 0x02, false, address);
531 }
532 
CmovsEd(REGISTER registerId,const CAddress & address)533 void CX86Assembler::CmovsEd(REGISTER registerId, const CAddress& address)
534 {
535 	WriteEvGvOp0F(0x48, false, address, registerId);
536 }
537 
CmovnsEd(REGISTER registerId,const CAddress & address)538 void CX86Assembler::CmovnsEd(REGISTER registerId, const CAddress& address)
539 {
540 	WriteEvGvOp0F(0x49, false, address, registerId);
541 }
542 
CmpEd(REGISTER registerId,const CAddress & address)543 void CX86Assembler::CmpEd(REGISTER registerId, const CAddress& address)
544 {
545 	WriteEvGvOp(0x3B, false, address, registerId);
546 }
547 
CmpEq(REGISTER nRegister,const CAddress & Address)548 void CX86Assembler::CmpEq(REGISTER nRegister, const CAddress& Address)
549 {
550 	WriteEvGvOp(0x3B, true, Address, nRegister);
551 }
552 
CmpIb(const CAddress & address,uint8 constant)553 void CX86Assembler::CmpIb(const CAddress& address, uint8 constant)
554 {
555 	assert(!address.NeedsExtendedByteAddress());
556 	WriteEvIb(0x07, address, constant);
557 }
558 
CmpId(const CAddress & address,uint32 constant)559 void CX86Assembler::CmpId(const CAddress& address, uint32 constant)
560 {
561 	WriteEvId(0x07, address, constant);
562 }
563 
CmpIq(const CAddress & Address,uint64 nConstant)564 void CX86Assembler::CmpIq(const CAddress& Address, uint64 nConstant)
565 {
566 	WriteEvIq(0x07, Address, nConstant);
567 }
568 
Cdq()569 void CX86Assembler::Cdq()
570 {
571 	WriteByte(0x99);
572 }
573 
DivEd(const CAddress & address)574 void CX86Assembler::DivEd(const CAddress& address)
575 {
576 	WriteEvOp(0xF7, 0x06, false, address);
577 }
578 
IdivEd(const CAddress & address)579 void CX86Assembler::IdivEd(const CAddress& address)
580 {
581 	WriteEvOp(0xF7, 0x07, false, address);
582 }
583 
ImulEw(const CAddress & address)584 void CX86Assembler::ImulEw(const CAddress& address)
585 {
586 	WriteByte(0x66);
587 	WriteEvOp(0xF7, 0x05, false, address);
588 }
589 
ImulEd(const CAddress & address)590 void CX86Assembler::ImulEd(const CAddress& address)
591 {
592 	WriteEvOp(0xF7, 0x05, false, address);
593 }
594 
Int3()595 void CX86Assembler::Int3()
596 {
597 	WriteByte(0xCC);
598 }
599 
JbJx(LABEL label)600 void CX86Assembler::JbJx(LABEL label)
601 {
602 	CreateLabelReference(label, JMP_B);
603 }
604 
JbeJx(LABEL label)605 void CX86Assembler::JbeJx(LABEL label)
606 {
607 	CreateLabelReference(label, JMP_BE);
608 }
609 
JnbJx(LABEL label)610 void CX86Assembler::JnbJx(LABEL label)
611 {
612 	CreateLabelReference(label, JMP_NB);
613 }
614 
JlJx(LABEL label)615 void CX86Assembler::JlJx(LABEL label)
616 {
617 	CreateLabelReference(label, JMP_L);
618 }
619 
JleJx(LABEL label)620 void CX86Assembler::JleJx(LABEL label)
621 {
622 	CreateLabelReference(label, JMP_LE);
623 }
624 
JnlJx(LABEL label)625 void CX86Assembler::JnlJx(LABEL label)
626 {
627 	CreateLabelReference(label, JMP_NL);
628 }
629 
JnleJx(LABEL label)630 void CX86Assembler::JnleJx(LABEL label)
631 {
632 	CreateLabelReference(label, JMP_NLE);
633 }
634 
JmpEd(const CAddress & address)635 void CX86Assembler::JmpEd(const CAddress& address)
636 {
637 	WriteEvOp(0xFF, 0x04, false, address);
638 }
639 
JmpJx(LABEL label)640 void CX86Assembler::JmpJx(LABEL label)
641 {
642 	CreateLabelReference(label, JMP_ALWAYS);
643 }
644 
JzJx(LABEL label)645 void CX86Assembler::JzJx(LABEL label)
646 {
647 	CreateLabelReference(label, JMP_Z);
648 }
649 
JnzJx(LABEL label)650 void CX86Assembler::JnzJx(LABEL label)
651 {
652 	CreateLabelReference(label, JMP_NZ);
653 }
654 
JnbeJx(LABEL label)655 void CX86Assembler::JnbeJx(LABEL label)
656 {
657 	CreateLabelReference(label, JMP_NBE);
658 }
659 
JnoJx(LABEL label)660 void CX86Assembler::JnoJx(LABEL label)
661 {
662 	CreateLabelReference(label, JMP_NO);
663 }
664 
JnsJx(LABEL label)665 void CX86Assembler::JnsJx(LABEL label)
666 {
667 	CreateLabelReference(label, JMP_NS);
668 }
669 
LeaGd(REGISTER registerId,const CAddress & address)670 void CX86Assembler::LeaGd(REGISTER registerId, const CAddress& address)
671 {
672 	WriteEvGvOp(0x8D, false, address, registerId);
673 }
674 
LeaGq(REGISTER registerId,const CAddress & address)675 void CX86Assembler::LeaGq(REGISTER registerId, const CAddress& address)
676 {
677 	WriteEvGvOp(0x8D, true, address, registerId);
678 }
679 
MovEw(REGISTER registerId,const CAddress & address)680 void CX86Assembler::MovEw(REGISTER registerId, const CAddress& address)
681 {
682 	WriteByte(0x66);
683 	WriteEvGvOp(0x8B, false, address, registerId);
684 }
685 
MovEd(REGISTER nRegister,const CAddress & Address)686 void CX86Assembler::MovEd(REGISTER nRegister, const CAddress& Address)
687 {
688 	WriteEvGvOp(0x8B, false, Address, nRegister);
689 }
690 
MovEq(REGISTER nRegister,const CAddress & Address)691 void CX86Assembler::MovEq(REGISTER nRegister, const CAddress& Address)
692 {
693 	WriteEvGvOp(0x8B, true, Address, nRegister);
694 }
695 
MovGb(const CAddress & Address,BYTEREGISTER nRegister)696 void CX86Assembler::MovGb(const CAddress& Address, BYTEREGISTER nRegister)
697 {
698 	if(Address.NeedsExtendedByteAddress())
699 	{
700 		throw std::runtime_error("Invalid operation.");
701 	}
702 	WriteEbGbOp(0x88, false, Address, nRegister);
703 }
704 
MovGb(const CAddress & Address,REGISTER nRegister)705 void CX86Assembler::MovGb(const CAddress& Address, REGISTER nRegister)
706 {
707 	WriteEbGbOp(0x88, false, Address, nRegister);
708 }
709 
MovGw(const CAddress & Address,REGISTER nRegister)710 void CX86Assembler::MovGw(const CAddress& Address, REGISTER nRegister)
711 {
712 	WriteByte(0x66);
713 	WriteEvGvOp(0x89, false, Address, nRegister);
714 }
715 
MovGd(const CAddress & Address,REGISTER nRegister)716 void CX86Assembler::MovGd(const CAddress& Address, REGISTER nRegister)
717 {
718 	WriteEvGvOp(0x89, false, Address, nRegister);
719 }
720 
MovGq(const CAddress & Address,REGISTER nRegister)721 void CX86Assembler::MovGq(const CAddress& Address, REGISTER nRegister)
722 {
723 	WriteEvGvOp(0x89, true, Address, nRegister);
724 }
725 
MovId(REGISTER nRegister,uint32 nConstant)726 void CX86Assembler::MovId(REGISTER nRegister, uint32 nConstant)
727 {
728 	CAddress Address(MakeRegisterAddress(nRegister));
729 	WriteRexByte(false, Address);
730 	WriteByte(0xB8 | Address.ModRm.nRM);
731 	WriteDWord(nConstant);
732 }
733 
MovIq(REGISTER registerId,uint64 constant)734 void CX86Assembler::MovIq(REGISTER registerId, uint64 constant)
735 {
736 	CAddress address(MakeRegisterAddress(registerId));
737 	WriteRexByte(true, address);
738 	WriteByte(0xB8 | address.ModRm.nRM);
739 	WriteDWord(static_cast<uint32>(constant & 0xFFFFFFFF));
740 	WriteDWord(static_cast<uint32>(constant >> 32));
741 }
742 
MovIb(const CX86Assembler::CAddress & address,uint8 constant)743 void CX86Assembler::MovIb(const CX86Assembler::CAddress& address, uint8 constant)
744 {
745 	assert(!address.NeedsExtendedByteAddress());
746 
747 	WriteRexByte(false, address);
748 	CAddress newAddress(address);
749 	newAddress.ModRm.nFnReg = 0x00;
750 
751 	WriteByte(0xC6);
752 	newAddress.Write(&m_tmpStream);
753 	WriteByte(constant);
754 }
755 
MovIw(const CX86Assembler::CAddress & address,uint16 constant)756 void CX86Assembler::MovIw(const CX86Assembler::CAddress& address, uint16 constant)
757 {
758 	WriteByte(0x66);
759 	WriteRexByte(false, address);
760 	CAddress newAddress(address);
761 	newAddress.ModRm.nFnReg = 0x00;
762 
763 	WriteByte(0xC7);
764 	newAddress.Write(&m_tmpStream);
765 	WriteWord(constant);
766 }
767 
MovId(const CX86Assembler::CAddress & address,uint32 constant)768 void CX86Assembler::MovId(const CX86Assembler::CAddress& address, uint32 constant)
769 {
770 	WriteRexByte(false, address);
771 	CAddress newAddress(address);
772 	newAddress.ModRm.nFnReg = 0x00;
773 
774 	WriteByte(0xC7);
775 	newAddress.Write(&m_tmpStream);
776 	WriteDWord(constant);
777 }
778 
MovsxEb(REGISTER registerId,const CAddress & address)779 void CX86Assembler::MovsxEb(REGISTER registerId, const CAddress& address)
780 {
781 	WriteEbGvOp0F(0xBE, false, address, registerId);
782 }
783 
MovsxEw(REGISTER registerId,const CAddress & address)784 void CX86Assembler::MovsxEw(REGISTER registerId, const CAddress& address)
785 {
786 	WriteEvGvOp0F(0xBF, false, address, registerId);
787 }
788 
MovzxEb(REGISTER registerId,const CAddress & address)789 void CX86Assembler::MovzxEb(REGISTER registerId, const CAddress& address)
790 {
791 	WriteEbGvOp0F(0xB6, false, address, registerId);
792 }
793 
MovzxEw(REGISTER registerId,const CAddress & address)794 void CX86Assembler::MovzxEw(REGISTER registerId, const CAddress& address)
795 {
796 	WriteEvGvOp0F(0xB7, false, address, registerId);
797 }
798 
MulEd(const CAddress & address)799 void CX86Assembler::MulEd(const CAddress& address)
800 {
801 	WriteEvOp(0xF7, 0x04, false, address);
802 }
803 
NegEd(const CAddress & address)804 void CX86Assembler::NegEd(const CAddress& address)
805 {
806 	WriteEvOp(0xF7, 0x03, false, address);
807 }
808 
Nop()809 void CX86Assembler::Nop()
810 {
811 	WriteByte(0x90);
812 }
813 
NotEd(const CAddress & address)814 void CX86Assembler::NotEd(const CAddress& address)
815 {
816 	WriteEvOp(0xF7, 0x02, false, address);
817 }
818 
OrEd(REGISTER registerId,const CAddress & address)819 void CX86Assembler::OrEd(REGISTER registerId, const CAddress& address)
820 {
821 	WriteEvGvOp(0x0B, false, address, registerId);
822 }
823 
OrId(const CAddress & address,uint32 constant)824 void CX86Assembler::OrId(const CAddress& address, uint32 constant)
825 {
826 	WriteEvId(0x01, address, constant);
827 }
828 
Pop(REGISTER registerId)829 void CX86Assembler::Pop(REGISTER registerId)
830 {
831 	CAddress Address(MakeRegisterAddress(registerId));
832 	WriteRexByte(false, Address);
833 	WriteByte(0x58 | Address.ModRm.nRM);
834 }
835 
Push(REGISTER registerId)836 void CX86Assembler::Push(REGISTER registerId)
837 {
838 	CAddress Address(MakeRegisterAddress(registerId));
839 	WriteRexByte(false, Address);
840 	WriteByte(0x50 | Address.ModRm.nRM);
841 }
842 
PushEd(const CAddress & address)843 void CX86Assembler::PushEd(const CAddress& address)
844 {
845 	WriteEvOp(0xFF, 0x06, false, address);
846 }
847 
PushId(uint32 value)848 void CX86Assembler::PushId(uint32 value)
849 {
850 	WriteByte(0x68);
851 	WriteDWord(value);
852 }
853 
RclEd(const CAddress & address,uint8 amount)854 void CX86Assembler::RclEd(const CAddress& address, uint8 amount)
855 {
856 	WriteEvOp(0xC1, 0x02, false, address);
857 	WriteByte(amount);
858 }
859 
RepMovsb()860 void CX86Assembler::RepMovsb()
861 {
862 	WriteByte(0xF3);
863 	WriteByte(0xA4);
864 }
865 
Ret()866 void CX86Assembler::Ret()
867 {
868 	WriteByte(0xC3);
869 }
870 
SarEd(const CAddress & address)871 void CX86Assembler::SarEd(const CAddress& address)
872 {
873 	WriteEvOp(0xD3, 0x07, false, address);
874 }
875 
SarEd(const CAddress & address,uint8 amount)876 void CX86Assembler::SarEd(const CAddress& address, uint8 amount)
877 {
878 	WriteEvOp(0xC1, 0x07, false, address);
879 	WriteByte(amount);
880 }
881 
SarEq(const CAddress & address)882 void CX86Assembler::SarEq(const CAddress& address)
883 {
884 	WriteEvOp(0xD3, 0x07, true, address);
885 }
886 
SarEq(const CAddress & address,uint8 amount)887 void CX86Assembler::SarEq(const CAddress& address, uint8 amount)
888 {
889 	WriteEvOp(0xC1, 0x07, true, address);
890 	WriteByte(amount);
891 }
892 
SbbEd(REGISTER registerId,const CAddress & address)893 void CX86Assembler::SbbEd(REGISTER registerId, const CAddress& address)
894 {
895 	WriteEvGvOp(0x1B, false, address, registerId);
896 }
897 
SbbId(const CAddress & Address,uint32 nConstant)898 void CX86Assembler::SbbId(const CAddress& Address, uint32 nConstant)
899 {
900 	WriteEvId(0x03, Address, nConstant);
901 }
902 
SetaEb(const CAddress & address)903 void CX86Assembler::SetaEb(const CAddress& address)
904 {
905 	WriteEbOp_0F(0x97, 0x00, address);
906 }
907 
SetaeEb(const CAddress & address)908 void CX86Assembler::SetaeEb(const CAddress& address)
909 {
910 	throw std::exception();
911 }
912 
SetbEb(const CAddress & address)913 void CX86Assembler::SetbEb(const CAddress& address)
914 {
915 	WriteEbOp_0F(0x92, 0x00, address);
916 }
917 
SetbeEb(const CAddress & address)918 void CX86Assembler::SetbeEb(const CAddress& address)
919 {
920 	WriteEbOp_0F(0x96, 0x00, address);
921 }
922 
SeteEb(const CAddress & address)923 void CX86Assembler::SeteEb(const CAddress& address)
924 {
925 	WriteEbOp_0F(0x94, 0x00, address);
926 }
927 
SetneEb(const CAddress & address)928 void CX86Assembler::SetneEb(const CAddress& address)
929 {
930 	WriteEbOp_0F(0x95, 0x00, address);
931 }
932 
SetlEb(const CAddress & address)933 void CX86Assembler::SetlEb(const CAddress& address)
934 {
935 	WriteEbOp_0F(0x9C, 0x00, address);
936 }
937 
SetleEb(const CAddress & address)938 void CX86Assembler::SetleEb(const CAddress& address)
939 {
940 	WriteEbOp_0F(0x9E, 0x00, address);
941 }
942 
SetgEb(const CAddress & address)943 void CX86Assembler::SetgEb(const CAddress& address)
944 {
945 	WriteEbOp_0F(0x9F, 0x00, address);
946 }
947 
ShlEd(const CAddress & address)948 void CX86Assembler::ShlEd(const CAddress& address)
949 {
950 	WriteEvOp(0xD3, 0x04, false, address);
951 }
952 
ShlEd(const CAddress & address,uint8 amount)953 void CX86Assembler::ShlEd(const CAddress& address, uint8 amount)
954 {
955 	WriteEvOp(0xC1, 0x04, false, address);
956 	WriteByte(amount);
957 }
958 
ShlEq(const CAddress & address)959 void CX86Assembler::ShlEq(const CAddress& address)
960 {
961 	WriteEvOp(0xD3, 0x04, true, address);
962 }
963 
ShlEq(const CAddress & address,uint8 amount)964 void CX86Assembler::ShlEq(const CAddress& address, uint8 amount)
965 {
966 	WriteEvOp(0xC1, 0x04, true, address);
967 	WriteByte(amount);
968 }
969 
ShrEd(const CAddress & address)970 void CX86Assembler::ShrEd(const CAddress& address)
971 {
972 	WriteEvOp(0xD3, 0x05, false, address);
973 }
974 
ShrEd(const CAddress & address,uint8 amount)975 void CX86Assembler::ShrEd(const CAddress& address, uint8 amount)
976 {
977 	WriteEvOp(0xC1, 0x05, false, address);
978 	WriteByte(amount);
979 }
980 
ShrEq(const CAddress & address)981 void CX86Assembler::ShrEq(const CAddress& address)
982 {
983 	WriteEvOp(0xD3, 0x05, true, address);
984 }
985 
ShrEq(const CAddress & address,uint8 amount)986 void CX86Assembler::ShrEq(const CAddress& address, uint8 amount)
987 {
988 	WriteEvOp(0xC1, 0x05, true, address);
989 	WriteByte(amount);
990 }
991 
ShldEd(const CAddress & address,REGISTER registerId)992 void CX86Assembler::ShldEd(const CAddress& address, REGISTER registerId)
993 {
994 	WriteByte(0x0F);
995 	WriteEvGvOp(0xA5, false, address, registerId);
996 }
997 
ShldEd(const CAddress & address,REGISTER registerId,uint8 amount)998 void CX86Assembler::ShldEd(const CAddress& address, REGISTER registerId, uint8 amount)
999 {
1000 	WriteByte(0x0F);
1001 	WriteEvGvOp(0xA4, false, address, registerId);
1002 	WriteByte(amount);
1003 }
1004 
ShrdEd(const CAddress & address,REGISTER registerId)1005 void CX86Assembler::ShrdEd(const CAddress& address, REGISTER registerId)
1006 {
1007 	WriteByte(0x0F);
1008 	WriteEvGvOp(0xAD, false, address, registerId);
1009 }
1010 
ShrdEd(const CAddress & address,REGISTER registerId,uint8 amount)1011 void CX86Assembler::ShrdEd(const CAddress& address, REGISTER registerId, uint8 amount)
1012 {
1013 	WriteByte(0x0F);
1014 	WriteEvGvOp(0xAC, false, address, registerId);
1015 	WriteByte(amount);
1016 }
1017 
SubEd(REGISTER nRegister,const CAddress & Address)1018 void CX86Assembler::SubEd(REGISTER nRegister, const CAddress& Address)
1019 {
1020 	WriteEvGvOp(0x2B, false, Address, nRegister);
1021 }
1022 
SubEq(REGISTER nRegister,const CAddress & Address)1023 void CX86Assembler::SubEq(REGISTER nRegister, const CAddress& Address)
1024 {
1025 	WriteEvGvOp(0x2B, true, Address, nRegister);
1026 }
1027 
SubId(const CAddress & Address,uint32 nConstant)1028 void CX86Assembler::SubId(const CAddress& Address, uint32 nConstant)
1029 {
1030 	WriteEvId(0x05, Address, nConstant);
1031 }
1032 
SubIq(const CAddress & address,uint64 constant)1033 void CX86Assembler::SubIq(const CAddress& address, uint64 constant)
1034 {
1035 	WriteEvIq(0x05, address, constant);
1036 }
1037 
TestEb(BYTEREGISTER registerId,const CAddress & address)1038 void CX86Assembler::TestEb(BYTEREGISTER registerId, const CAddress& address)
1039 {
1040 	if(address.NeedsExtendedByteAddress())
1041 	{
1042 		throw std::runtime_error("Invalid operation.");
1043 	}
1044 	WriteEbGbOp(0x84, false, address, registerId);
1045 }
1046 
TestEd(REGISTER registerId,const CAddress & address)1047 void CX86Assembler::TestEd(REGISTER registerId, const CAddress& address)
1048 {
1049 	WriteEvGvOp(0x85, false, address, registerId);
1050 }
1051 
TestEq(REGISTER registerId,const CAddress & address)1052 void CX86Assembler::TestEq(REGISTER registerId, const CAddress& address)
1053 {
1054 	WriteEvGvOp(0x85, true, address, registerId);
1055 }
1056 
XorEd(REGISTER registerId,const CAddress & address)1057 void CX86Assembler::XorEd(REGISTER registerId, const CAddress& address)
1058 {
1059 	WriteEvGvOp(0x33, false, address, registerId);
1060 }
1061 
XorId(const CAddress & address,uint32 constant)1062 void CX86Assembler::XorId(const CAddress& address, uint32 constant)
1063 {
1064 	WriteEvId(0x06, address, constant);
1065 }
1066 
XorGd(const CAddress & Address,REGISTER nRegister)1067 void CX86Assembler::XorGd(const CAddress& Address, REGISTER nRegister)
1068 {
1069 	WriteEvGvOp(0x31, false, Address, nRegister);
1070 }
1071 
XorGq(const CAddress & Address,REGISTER nRegister)1072 void CX86Assembler::XorGq(const CAddress& Address, REGISTER nRegister)
1073 {
1074 	WriteEvGvOp(0x31, true, Address, nRegister);
1075 }
1076 
WriteRexByte(bool nIs64,const CAddress & Address)1077 void CX86Assembler::WriteRexByte(bool nIs64, const CAddress& Address)
1078 {
1079 	REGISTER nTemp = rAX;
1080 	WriteRexByte(nIs64, Address, nTemp);
1081 }
1082 
WriteRexByte(bool nIs64,const CAddress & Address,REGISTER & nRegister,bool forceWrite)1083 void CX86Assembler::WriteRexByte(bool nIs64, const CAddress& Address, REGISTER& nRegister, bool forceWrite)
1084 {
1085 	if((nIs64) || (Address.nIsExtendedModRM) || (Address.nIsExtendedSib) || (nRegister > 7) || forceWrite)
1086 	{
1087 		uint8 nByte = 0x40;
1088 		nByte |= nIs64 ? 0x8 : 0x0;
1089 		nByte |= (nRegister > 7) ? 0x04 : 0x0;
1090 		nByte |= Address.nIsExtendedSib ? 0x02 : 0x0;
1091 		nByte |= Address.nIsExtendedModRM ? 0x1 : 0x0;
1092 
1093 		nRegister = static_cast<REGISTER>(nRegister & 7);
1094 
1095 		WriteByte(nByte);
1096 	}
1097 }
1098 
WriteEbOp_0F(uint8 opcode,uint8 subOpcode,const CAddress & address)1099 void CX86Assembler::WriteEbOp_0F(uint8 opcode, uint8 subOpcode, const CAddress& address)
1100 {
1101 	auto dummyReg = CX86Assembler::rAX;
1102 	bool forcedWrite = address.NeedsExtendedByteAddress();
1103 	WriteRexByte(false, address, dummyReg, forcedWrite);
1104 	WriteByte(0x0F);
1105 	CAddress newAddress(address);
1106 	newAddress.ModRm.nFnReg = subOpcode;
1107 	WriteByte(opcode);
1108 	newAddress.Write(&m_tmpStream);
1109 }
1110 
WriteEbGbOp(uint8 nOp,bool nIs64,const CAddress & Address,REGISTER nRegister)1111 void CX86Assembler::WriteEbGbOp(uint8 nOp, bool nIs64, const CAddress& Address, REGISTER nRegister)
1112 {
1113 	WriteRexByte(nIs64, Address, nRegister, true);
1114 	CAddress NewAddress(Address);
1115 	NewAddress.ModRm.nFnReg = nRegister;
1116 	WriteByte(nOp);
1117 	NewAddress.Write(&m_tmpStream);
1118 }
1119 
WriteEbGbOp(uint8 nOp,bool nIs64,const CAddress & Address,BYTEREGISTER nRegister)1120 void CX86Assembler::WriteEbGbOp(uint8 nOp, bool nIs64, const CAddress& Address, BYTEREGISTER nRegister)
1121 {
1122 	CAddress NewAddress(Address);
1123 	NewAddress.ModRm.nFnReg = nRegister;
1124 	WriteByte(nOp);
1125 	NewAddress.Write(&m_tmpStream);
1126 }
1127 
WriteEbGvOp0F(uint8 op,bool is64,const CAddress & address,REGISTER registerId)1128 void CX86Assembler::WriteEbGvOp0F(uint8 op, bool is64, const CAddress& address, REGISTER registerId)
1129 {
1130 	assert(!(address.usesLegacyByteRegister && (registerId > 7)));
1131 	bool forcedWrite = address.NeedsExtendedByteAddress();
1132 	WriteRexByte(is64, address, registerId, forcedWrite);
1133 	WriteByte(0x0F);
1134 	CAddress NewAddress(address);
1135 	NewAddress.ModRm.nFnReg = registerId;
1136 	WriteByte(op);
1137 	NewAddress.Write(&m_tmpStream);
1138 }
1139 
WriteEvOp(uint8 opcode,uint8 subOpcode,bool is64,const CAddress & address)1140 void CX86Assembler::WriteEvOp(uint8 opcode, uint8 subOpcode, bool is64, const CAddress& address)
1141 {
1142 	WriteRexByte(is64, address);
1143 	CAddress newAddress(address);
1144 	newAddress.ModRm.nFnReg = subOpcode;
1145 	WriteByte(opcode);
1146 	newAddress.Write(&m_tmpStream);
1147 }
1148 
WriteEvGvOp(uint8 nOp,bool nIs64,const CAddress & Address,REGISTER nRegister)1149 void CX86Assembler::WriteEvGvOp(uint8 nOp, bool nIs64, const CAddress& Address, REGISTER nRegister)
1150 {
1151 	WriteRexByte(nIs64, Address, nRegister);
1152 	CAddress NewAddress(Address);
1153 	NewAddress.ModRm.nFnReg = nRegister;
1154 	WriteByte(nOp);
1155 	NewAddress.Write(&m_tmpStream);
1156 }
1157 
WriteEvGvOp0F(uint8 nOp,bool nIs64,const CAddress & Address,REGISTER nRegister)1158 void CX86Assembler::WriteEvGvOp0F(uint8 nOp, bool nIs64, const CAddress& Address, REGISTER nRegister)
1159 {
1160 	WriteRexByte(nIs64, Address, nRegister);
1161 	WriteByte(0x0F);
1162 	CAddress NewAddress(Address);
1163 	NewAddress.ModRm.nFnReg = nRegister;
1164 	WriteByte(nOp);
1165 	NewAddress.Write(&m_tmpStream);
1166 }
1167 
WriteEvIb(uint8 op,const CAddress & address,uint8 constant)1168 void CX86Assembler::WriteEvIb(uint8 op, const CAddress& address, uint8 constant)
1169 {
1170 	WriteRexByte(false, address);
1171 	CAddress newAddress(address);
1172 	newAddress.ModRm.nFnReg = op;
1173 	WriteByte(0x80);
1174 	newAddress.Write(&m_tmpStream);
1175 	WriteByte(constant);
1176 }
1177 
WriteEvId(uint8 nOp,const CAddress & Address,uint32 nConstant)1178 void CX86Assembler::WriteEvId(uint8 nOp, const CAddress& Address, uint32 nConstant)
1179 {
1180 	//0x81 -> Id
1181 	//0x83 -> Ib
1182 
1183 	WriteRexByte(false, Address);
1184 	CAddress NewAddress(Address);
1185 	NewAddress.ModRm.nFnReg = nOp;
1186 
1187 	if(GetMinimumConstantSize(nConstant) == 1)
1188 	{
1189 		WriteByte(0x83);
1190 		NewAddress.Write(&m_tmpStream);
1191 		WriteByte(static_cast<uint8>(nConstant));
1192 	}
1193 	else
1194 	{
1195 		WriteByte(0x81);
1196 		NewAddress.Write(&m_tmpStream);
1197 		WriteDWord(nConstant);
1198 	}
1199 }
1200 
WriteEvIq(uint8 nOp,const CAddress & Address,uint64 nConstant)1201 void CX86Assembler::WriteEvIq(uint8 nOp, const CAddress& Address, uint64 nConstant)
1202 {
1203 	unsigned int nConstantSize(GetMinimumConstantSize64(nConstant));
1204 	assert(nConstantSize <= 4);
1205 
1206 	WriteRexByte(true, Address);
1207 	CAddress NewAddress(Address);
1208 	NewAddress.ModRm.nFnReg = nOp;
1209 
1210 	if(nConstantSize == 1)
1211 	{
1212 		WriteByte(0x83);
1213 		NewAddress.Write(&m_tmpStream);
1214 		WriteByte(static_cast<uint8>(nConstant));
1215 	}
1216 	else
1217 	{
1218 		WriteByte(0x81);
1219 		NewAddress.Write(&m_tmpStream);
1220 		WriteDWord(static_cast<uint32>(nConstant));
1221 	}
1222 }
1223 
CreateLabelReference(LABEL label,JMP_TYPE type)1224 void CX86Assembler::CreateLabelReference(LABEL label, JMP_TYPE type)
1225 {
1226 	assert(m_currentLabel != NULL);
1227 
1228 	LABELREF reference;
1229 	reference.label			= label;
1230 	reference.offset		= static_cast<uint32>(m_tmpStream.Tell());
1231 	reference.type			= type;
1232 
1233 	m_currentLabel->labelRefs.push_back(reference);
1234 }
1235 
HasByteRegister(REGISTER registerId)1236 bool CX86Assembler::HasByteRegister(REGISTER registerId)
1237 {
1238 	return (registerId < rSP);
1239 }
1240 
GetByteRegister(REGISTER registerId)1241 CX86Assembler::BYTEREGISTER CX86Assembler::GetByteRegister(REGISTER registerId)
1242 {
1243 	assert(HasByteRegister(registerId));
1244 	return static_cast<BYTEREGISTER>(registerId);
1245 }
1246 
GetMinimumConstantSize(uint32 nConstant)1247 unsigned int CX86Assembler::GetMinimumConstantSize(uint32 nConstant)
1248 {
1249 	if((static_cast<int32>(nConstant) >= -128) && (static_cast<int32>(nConstant) <= 127))
1250 	{
1251 		return 1;
1252 	}
1253 	return 4;
1254 }
1255 
GetMinimumConstantSize64(uint64 nConstant)1256 unsigned int CX86Assembler::GetMinimumConstantSize64(uint64 nConstant)
1257 {
1258 	if((static_cast<int64>(nConstant) >= -128) && (static_cast<int64>(nConstant) <= 127))
1259 	{
1260 		return 1;
1261 	}
1262 	if((static_cast<int64>(nConstant) >= -2147483647) && (static_cast<int64>(nConstant) <= 2147483647))
1263 	{
1264 		return 4;
1265 	}
1266 	return 8;
1267 }
1268 
GetJumpSize(JMP_TYPE type,JMP_LENGTH length)1269 unsigned int CX86Assembler::GetJumpSize(JMP_TYPE type, JMP_LENGTH length)
1270 {
1271 	if(length == JMP_NEAR)
1272 	{
1273 		return 2;
1274 	}
1275 	else
1276 	{
1277 		if(type == JMP_ALWAYS)
1278 		{
1279 			return 5;
1280 		}
1281 		else
1282 		{
1283 			return 6;
1284 		}
1285 	}
1286 }
1287 
WriteJump(Framework::CStream * stream,JMP_TYPE type,JMP_LENGTH length,uint32 offset)1288 void CX86Assembler::WriteJump(Framework::CStream* stream, JMP_TYPE type, JMP_LENGTH length, uint32 offset)
1289 {
1290 	if(length == JMP_FAR)
1291 	{
1292 		switch(type)
1293 		{
1294 		case JMP_ALWAYS:
1295 			stream->Write8(0xE9);
1296 			break;
1297 		default:
1298 			stream->Write8(0x0F);
1299 			stream->Write8(0x80 | static_cast<uint8>(type));
1300 			break;
1301 		}
1302 		stream->Write32(offset);
1303 	}
1304 	else
1305 	{
1306 		switch(type)
1307 		{
1308 		case JMP_ALWAYS:
1309 			stream->Write8(0xEB);
1310 			break;
1311 		default:
1312 			stream->Write8(0x70 | static_cast<uint8>(type));
1313 			break;
1314 		}
1315 		stream->Write8(static_cast<uint8>(offset));
1316 	}
1317 }
1318 
WriteByte(uint8 nByte)1319 void CX86Assembler::WriteByte(uint8 nByte)
1320 {
1321 	m_tmpStream.Write8(nByte);
1322 }
1323 
WriteWord(uint16 word)1324 void CX86Assembler::WriteWord(uint16 word)
1325 {
1326 	m_tmpStream.Write16(word);
1327 }
1328 
WriteDWord(uint32 nDWord)1329 void CX86Assembler::WriteDWord(uint32 nDWord)
1330 {
1331 	//Endianess should be good, unless we target a different processor...
1332 	m_tmpStream.Write32(nDWord);
1333 }
1334 
1335 /////////////////////////////////////////////////
1336 /////////////////////////////////////////////////
1337 
CAddress()1338 CX86Assembler::CAddress::CAddress()
1339 {
1340 	nOffset = 0;
1341 	ModRm.nByte = 0;
1342 	sib.byteValue = 0;
1343 	nIsExtendedModRM = false;
1344 	nIsExtendedSib = false;
1345 	usesLegacyByteRegister = false;
1346 }
1347 
Write(Framework::CStream * stream)1348 void CX86Assembler::CAddress::Write(Framework::CStream* stream)
1349 {
1350 	stream->Write8(ModRm.nByte);
1351 
1352 	if(HasSib())
1353 	{
1354 		stream->Write8(sib.byteValue);
1355 	}
1356 
1357 	if(ModRm.nMod == 1)
1358 	{
1359 		stream->Write8(static_cast<uint8>(nOffset));
1360 	}
1361 	else if(ModRm.nMod == 2)
1362 	{
1363 		stream->Write32(nOffset);
1364 	}
1365 }
1366 
HasSib() const1367 bool CX86Assembler::CAddress::HasSib() const
1368 {
1369 	if(ModRm.nMod == 3) return false;
1370 	return ModRm.nRM == 4;
1371 }
1372 
NeedsExtendedByteAddress() const1373 bool CX86Assembler::CAddress::NeedsExtendedByteAddress() const
1374 {
1375 	return (ModRm.nMod == 0x03) && !usesLegacyByteRegister;
1376 }
1377