1 | #!/usr/bin/env python
|
---|
2 | # -*- coding: utf-8 -*-
|
---|
3 | # $Id: bs3-cpu-basic-3-high-lea64.py 102278 2023-11-23 15:44:17Z vboxsync $
|
---|
4 | # pylint: disable=invalid-name
|
---|
5 |
|
---|
6 | """
|
---|
7 | Generates the assembly body of the 64-bit lea testcase.
|
---|
8 |
|
---|
9 | Nasm consumes too much memory (>19GB) doing this via the preprocessor, it also
|
---|
10 | takes its good time about it. This script takes 2-3 seconds and nasm only
|
---|
11 | consumes a few hundred MB of memory processing it (takes some 40 seconds, though).
|
---|
12 | """
|
---|
13 |
|
---|
14 | from __future__ import print_function;
|
---|
15 |
|
---|
16 | __copyright__ = \
|
---|
17 | """
|
---|
18 | Copyright (C) 2023 Oracle and/or its affiliates.
|
---|
19 |
|
---|
20 | This file is part of VirtualBox base platform packages, as
|
---|
21 | available from https://www.virtualbox.org.
|
---|
22 |
|
---|
23 | This program is free software; you can redistribute it and/or
|
---|
24 | modify it under the terms of the GNU General Public License
|
---|
25 | as published by the Free Software Foundation, in version 3 of the
|
---|
26 | License.
|
---|
27 |
|
---|
28 | This program is distributed in the hope that it will be useful, but
|
---|
29 | WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
30 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
31 | General Public License for more details.
|
---|
32 |
|
---|
33 | You should have received a copy of the GNU General Public License
|
---|
34 | along with this program; if not, see <https://www.gnu.org/licenses>.
|
---|
35 |
|
---|
36 | The contents of this file may alternatively be used under the terms
|
---|
37 | of the Common Development and Distribution License Version 1.0
|
---|
38 | (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
|
---|
39 | in the VirtualBox distribution, in which case the provisions of the
|
---|
40 | CDDL are applicable instead of those of the GPL.
|
---|
41 |
|
---|
42 | You may elect to license modified versions of this file under the
|
---|
43 | terms and conditions of either the GPL or the CDDL or both.
|
---|
44 |
|
---|
45 | SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
|
---|
46 | """
|
---|
47 | __version__ = "$Revision: 102278 $"
|
---|
48 |
|
---|
49 | # Standard python imports.
|
---|
50 | import random;
|
---|
51 | import sys;
|
---|
52 |
|
---|
53 | g_kasRegNames = [
|
---|
54 | 'rax',
|
---|
55 | 'rcx',
|
---|
56 | 'rdx',
|
---|
57 | 'rbx',
|
---|
58 | 'rsp',
|
---|
59 | 'rbp',
|
---|
60 | 'rsi',
|
---|
61 | 'rdi',
|
---|
62 | 'r8',
|
---|
63 | 'r9',
|
---|
64 | 'r10',
|
---|
65 | 'r11',
|
---|
66 | 'r12',
|
---|
67 | 'r13',
|
---|
68 | 'r14',
|
---|
69 | 'r15',
|
---|
70 | ];
|
---|
71 |
|
---|
72 | g_kaiRegValues = [
|
---|
73 | 0x1111111111111110,
|
---|
74 | 0x2222222222222202,
|
---|
75 | 0x3333333333333033,
|
---|
76 | 0x4444444444440444,
|
---|
77 | 0x58595a5d51525356,
|
---|
78 | 0x5555555555555551,
|
---|
79 | 0x6666666666666616,
|
---|
80 | 0x7777777777777177,
|
---|
81 | 0x8888888888881888,
|
---|
82 | 0x9999999999999992,
|
---|
83 | 0xaaaaaaaaaaaaaa2a,
|
---|
84 | 0xbbbbbbbbbbbbb2bb,
|
---|
85 | 0xcccccccccccc2ccc,
|
---|
86 | 0xddddddddddddddd3,
|
---|
87 | 0xeeeeeeeeeeeeee3e,
|
---|
88 | 0xfffffffffffff3ff,
|
---|
89 | ];
|
---|
90 |
|
---|
91 | def x86ModRmMake(iMod, iReg, iRm):
|
---|
92 | """ See X86_MODRM_MAKE. """
|
---|
93 | return (iMod << 6) | ((iReg & 7) << 3) | (iRm & 7);
|
---|
94 |
|
---|
95 | def x86SibMake(iBase, iIndex, cShift):
|
---|
96 | """ X86_SIB_MAKE(iBase & 7, iIndex & 7, cShift) """
|
---|
97 | return (cShift << 6) | ((iIndex & 7) << 3) | (iBase & 7);
|
---|
98 |
|
---|
99 | def x86RexW3(iBase, iIndex, iDstReg):
|
---|
100 | # db X86_OP_REX_W | ((iBase & 8) >> 3) | ((iIndex & 8) >> 2) | ((iDstReg & 8) >> 1)
|
---|
101 | return 0x48 | ((iBase & 8) >> 3) | ((iIndex & 8) >> 2) | ((iDstReg & 8) >> 1);
|
---|
102 |
|
---|
103 | def x86Rex3(iBase, iIndex, iDstReg):
|
---|
104 | # db X86_OP_REX | ((iBase & 8) >> 3) | ((iIndex & 8) >> 2) | ((iDstReg & 8) >> 1)
|
---|
105 | return 0x40 | ((iBase & 8) >> 3) | ((iIndex & 8) >> 2) | ((iDstReg & 8) >> 1);
|
---|
106 |
|
---|
107 | def generateTraceAndLoad(fLoadRsp, fTracing):
|
---|
108 | """ Loads registers and traces current position if requested. """
|
---|
109 | if fTracing:
|
---|
110 | asRet = ['mov dword [rel BS3_DATA_NM(g_bs3CpuBasic3_lea_trace)], $',];
|
---|
111 | else:
|
---|
112 | asRet = [];
|
---|
113 | asRet.append('call .load_regs');
|
---|
114 | if fLoadRsp:
|
---|
115 | asRet.append('mov rsp, %#x' % (g_kaiRegValues[4], ));
|
---|
116 | return asRet;
|
---|
117 |
|
---|
118 | def cenerateCompareAndCheckSib(sDstRegName, iValue, fRestoreRsp):
|
---|
119 | """ Checks that sDstRegName contains iValue, executing int3 if it doesn't and restoring RSP first if requested. """
|
---|
120 | if -0x80000000 <= iValue <= 0x7fffffff:
|
---|
121 | asRet = [
|
---|
122 | 'cmp %s, %#x' % (sDstRegName, iValue),
|
---|
123 | ];
|
---|
124 | elif sDstRegName != 'rax':
|
---|
125 | asRet = [
|
---|
126 | 'mov rax, %#x' % (iValue,),
|
---|
127 | 'cmp %s, rax' % (sDstRegName,),
|
---|
128 | ];
|
---|
129 | else:
|
---|
130 | asRet = [
|
---|
131 | 'mov rcx, %#x' % (iValue),
|
---|
132 | 'cmp rax, rcx',
|
---|
133 | ];
|
---|
134 | if fRestoreRsp:
|
---|
135 | asRet += [
|
---|
136 | 'mov rdx, rsp',
|
---|
137 | 'mov rsp, [rel BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp)]',
|
---|
138 | ];
|
---|
139 | asRet += [
|
---|
140 | 'jz $+3',
|
---|
141 | 'int3'
|
---|
142 | ];
|
---|
143 | return asRet;
|
---|
144 |
|
---|
145 | def generateCompareAndCheckModRm(sDstRegName, iValue, sValue, fRestoreRsp):
|
---|
146 | """
|
---|
147 | Checks that sDstRegName contains iValue or sValue if not None,
|
---|
148 | executing int3 if it doesn't and restoring RSP first if requested.
|
---|
149 | """
|
---|
150 | if sValue:
|
---|
151 | asRet = [
|
---|
152 | 'cmp %s, %s' % (sDstRegName, sValue),
|
---|
153 | ];
|
---|
154 | elif -0x80000000 <= iValue <= 0x7fffffff:
|
---|
155 | asRet = [
|
---|
156 | 'cmp %s, %#x' % (sDstRegName, iValue),
|
---|
157 | ];
|
---|
158 | elif sDstRegName != 'rax':
|
---|
159 | asRet = [
|
---|
160 | 'mov rax, %#x' % (iValue,),
|
---|
161 | 'cmp %s, rax' % (sDstRegName,),
|
---|
162 | ];
|
---|
163 | else:
|
---|
164 | asRet = [
|
---|
165 | 'mov rcx, %#x' % (iValue),
|
---|
166 | 'cmp rax, rcx',
|
---|
167 | ];
|
---|
168 | if fRestoreRsp:
|
---|
169 | asRet += [
|
---|
170 | 'mov rdx, rsp',
|
---|
171 | 'mov rsp, [rel BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp)]',
|
---|
172 | ];
|
---|
173 | asRet += [
|
---|
174 | 'jz $+3',
|
---|
175 | 'int3'
|
---|
176 | ];
|
---|
177 | return asRet;
|
---|
178 |
|
---|
179 | def generateDispSib(iValue, iMod, iBase):
|
---|
180 | """ Generates the displacement part of the LEA instruction for the SIB variant. """
|
---|
181 | if iMod == 1: #X86_MOD_MEM1:
|
---|
182 | iDisp = random.randint(-128, 127);
|
---|
183 | return iValue + iDisp, ['db %d' % (iDisp,),];
|
---|
184 | if iMod == 2 or (iMod == 0 and (iBase & 7) == 5):
|
---|
185 | iDisp = random.randint(-0x80000000, 0x7fffffff);
|
---|
186 | return iValue + iDisp, ['dd %d' % (iDisp,),];
|
---|
187 | return iValue, [];
|
---|
188 |
|
---|
189 | def generateDispModRm(iValue, iMod, iMemReg, iLabelVar, f16Bit = False):
|
---|
190 | """ Generates the displacement part of the LEA instruction for the non-SIB variant. """
|
---|
191 | if iMod == 1: #X86_MOD_MEM1
|
---|
192 | iDisp = random.randint(-128, 127);
|
---|
193 | return iValue + iDisp, None, ['db %d' % (iDisp,),];
|
---|
194 | if iMod == 0 and (iMemReg & 7) == 5:
|
---|
195 | if f16Bit:
|
---|
196 | # Generate a known 16-bit value by trickery as we the iDstReg value is mixed.
|
---|
197 | # ASSUMES Bs3Text16 is 64KB aligned in the high DLL...
|
---|
198 | iValue = random.randint(0, 0x7fff);
|
---|
199 | return iValue, None, ['dd _Bs3Text16_StartOfSegment - $ - 4 + %d wrt BS3FLAT' % (iValue,),];
|
---|
200 | if iLabelVar & 1:
|
---|
201 | return iValue, '.test_label wrt BS3FLAT', ['dd .test_label - $ - 4',];
|
---|
202 | return iValue, '.load_regs wrt BS3FLAT', ['dd .load_regs - $ - 4',];
|
---|
203 | if iMod == 2: #X86_MOD_MEM4
|
---|
204 | iDisp = random.randint(-0x80000000, 0x7fffffff);
|
---|
205 | return iValue + iDisp, None, ['dd %d' % (iDisp,),];
|
---|
206 | return iValue, None, [];
|
---|
207 |
|
---|
208 | def generateLea64(oOut): # pylint: disable=too-many-statements
|
---|
209 | fTracing = False;
|
---|
210 |
|
---|
211 | #
|
---|
212 | # Loop thru all the modr/m memory encodings.
|
---|
213 | #
|
---|
214 | asLines = [];
|
---|
215 | for iMod in range(3):
|
---|
216 | for iDstReg in range(16):
|
---|
217 | sDstReg_Name = g_kasRegNames[iDstReg];
|
---|
218 | iDstReg_Value = g_kaiRegValues[iDstReg];
|
---|
219 | for iMemReg in range(16):
|
---|
220 | if (iMemReg & 7) == 4:
|
---|
221 | #
|
---|
222 | # SIB.
|
---|
223 | #
|
---|
224 | for iBase in range(16):
|
---|
225 | if (iBase & 7) == 5 and iMod == 0:
|
---|
226 | iBase_Value = 0
|
---|
227 | else:
|
---|
228 | iBase_Value = g_kaiRegValues[iBase];
|
---|
229 |
|
---|
230 | for iIndex in range(16):
|
---|
231 | if iIndex == 4:
|
---|
232 | iIndex_Value = 0;
|
---|
233 | else:
|
---|
234 | iIndex_Value = g_kaiRegValues[iIndex];
|
---|
235 |
|
---|
236 | for cShift in range(4):
|
---|
237 | fLoadRestoreRsp = iBase == 4 or iDstReg == 4;
|
---|
238 |
|
---|
239 | #
|
---|
240 | # LEA+SIB w/ 64-bit operand size and 64-bit address size.
|
---|
241 | #
|
---|
242 | asLines.extend(generateTraceAndLoad(fLoadRestoreRsp, fTracing));
|
---|
243 |
|
---|
244 | # lea
|
---|
245 | iValue = iBase_Value + (iIndex_Value << cShift)
|
---|
246 | asLines.append('db %#x, 8dh, %#x, %#x'
|
---|
247 | % (x86RexW3(iBase, iIndex, iDstReg), x86ModRmMake(iMod, iDstReg, iMemReg),
|
---|
248 | x86SibMake(iBase, iIndex, cShift),));
|
---|
249 | iValue, asAdd = generateDispSib(iValue, iMod, iBase);
|
---|
250 | asLines.extend(asAdd);
|
---|
251 | iValue &= 0xffffffffffffffff;
|
---|
252 |
|
---|
253 | # cmp iDstReg, iValue + jz + int3
|
---|
254 | asLines.extend(cenerateCompareAndCheckSib(sDstReg_Name, iValue, fLoadRestoreRsp));
|
---|
255 |
|
---|
256 |
|
---|
257 | #
|
---|
258 | # LEA+SIB w/ 64-bit operand size and 32-bit address size.
|
---|
259 | #
|
---|
260 | asLines.extend(generateTraceAndLoad(fLoadRestoreRsp, fTracing));
|
---|
261 |
|
---|
262 | # lea w/ X86_OP_PRF_SIZE_ADDR
|
---|
263 | iValue = iBase_Value + (iIndex_Value << cShift)
|
---|
264 | asLines.append('db 067h, %#x, 8dh, %#x, %#x'
|
---|
265 | % (x86RexW3(iBase, iIndex, iDstReg), x86ModRmMake(iMod, iDstReg, iMemReg),
|
---|
266 | x86SibMake(iBase, iIndex, cShift),));
|
---|
267 | iValue, asAdd = generateDispSib(iValue, iMod, iBase);
|
---|
268 | asLines.extend(asAdd);
|
---|
269 | iValue &= 0xffffffff;
|
---|
270 |
|
---|
271 | # cmp iDstReg, iValue + jz + int3
|
---|
272 | asLines.extend(cenerateCompareAndCheckSib(sDstReg_Name, iValue, fLoadRestoreRsp));
|
---|
273 |
|
---|
274 |
|
---|
275 | #
|
---|
276 | # LEA+SIB w/ 32-bit operand size and 64-bit address size.
|
---|
277 | #
|
---|
278 | asLines.extend(generateTraceAndLoad(fLoadRestoreRsp, fTracing));
|
---|
279 |
|
---|
280 | # lea
|
---|
281 | iValue = iBase_Value + (iIndex_Value << cShift);
|
---|
282 | if (iBase | iIndex | iDstReg) & 8:
|
---|
283 | asLines.append('db %#x' % (x86Rex3(iBase, iIndex, iDstReg),));
|
---|
284 | asLines.append('db 8dh, %#x, %#x'
|
---|
285 | % (x86ModRmMake(iMod, iDstReg, iMemReg), x86SibMake(iBase, iIndex, cShift),));
|
---|
286 | iValue, asAdd = generateDispSib(iValue, iMod, iBase);
|
---|
287 | asLines.extend(asAdd);
|
---|
288 | iValue &= 0xffffffff;
|
---|
289 |
|
---|
290 | # cmp iDstReg, iValue + jz + int3
|
---|
291 | asLines.extend(cenerateCompareAndCheckSib(sDstReg_Name, iValue, fLoadRestoreRsp));
|
---|
292 |
|
---|
293 |
|
---|
294 | #
|
---|
295 | # LEA+SIB w/ 32-bit operand size and 32-bit address size.
|
---|
296 | #
|
---|
297 | asLines.extend(generateTraceAndLoad(fLoadRestoreRsp, fTracing));
|
---|
298 |
|
---|
299 | # lea
|
---|
300 | iValue = iBase_Value + (iIndex_Value << cShift);
|
---|
301 | asLines.append('db 067h'); # X86_OP_PRF_SIZE_ADDR
|
---|
302 | if (iBase | iIndex | iDstReg) & 8:
|
---|
303 | asLines.append('db %#x' % (x86Rex3(iBase, iIndex, iDstReg),));
|
---|
304 | asLines.append('db 8dh, %#x, %#x'
|
---|
305 | % (x86ModRmMake(iMod, iDstReg, iMemReg), x86SibMake(iBase, iIndex, cShift),));
|
---|
306 | iValue, asAdd = generateDispSib(iValue, iMod, iBase);
|
---|
307 | asLines.extend(asAdd);
|
---|
308 | iValue &= 0xffffffff;
|
---|
309 |
|
---|
310 | # cmp iDstReg, iValue + jz + int3
|
---|
311 | asLines.extend(cenerateCompareAndCheckSib(sDstReg_Name, iValue, fLoadRestoreRsp));
|
---|
312 |
|
---|
313 |
|
---|
314 | #
|
---|
315 | # LEA+SIB w/ 16-bit operand size and 64-bit address size.
|
---|
316 | #
|
---|
317 | asLines.extend(generateTraceAndLoad(fLoadRestoreRsp, fTracing));
|
---|
318 |
|
---|
319 | # lea
|
---|
320 | iValue = iBase_Value + (iIndex_Value << cShift);
|
---|
321 | asLines.append('db 66h'); # X86_OP_PRF_SIZE_OP
|
---|
322 | if (iBase | iIndex | iDstReg) & 8:
|
---|
323 | asLines.append('db %#x' % (x86Rex3(iBase, iIndex, iDstReg),));
|
---|
324 | asLines.append('db 8dh, %#x, %#x'
|
---|
325 | % (x86ModRmMake(iMod, iDstReg, iMemReg), x86SibMake(iBase, iIndex, cShift),));
|
---|
326 | iValue, asAdd = generateDispSib(iValue, iMod, iBase);
|
---|
327 | asLines.extend(asAdd);
|
---|
328 | iValue = (iValue & 0xffff) | (iDstReg_Value & 0xffffffffffff0000);
|
---|
329 |
|
---|
330 | # cmp iDstReg, iValue + jz + int3
|
---|
331 | asLines.extend(cenerateCompareAndCheckSib(sDstReg_Name, iValue, fLoadRestoreRsp));
|
---|
332 |
|
---|
333 | #
|
---|
334 | # LEA+SIB w/ 16-bit operand size and 32-bit address size.
|
---|
335 | #
|
---|
336 | asLines.extend(generateTraceAndLoad(fLoadRestoreRsp, fTracing));
|
---|
337 |
|
---|
338 | # lea
|
---|
339 | iValue = iBase_Value + (iIndex_Value << cShift);
|
---|
340 | if cShift & 2:
|
---|
341 | asLines.append('db 066h, 067h'); # X86_OP_PRF_SIZE_OP, X86_OP_PRF_SIZE_ADDR
|
---|
342 | else:
|
---|
343 | asLines.append('db 067h, 066h'); # X86_OP_PRF_SIZE_ADDR, X86_OP_PRF_SIZE_OP
|
---|
344 | if (iBase | iIndex | iDstReg) & 8:
|
---|
345 | asLines.append('db %#x' % (x86Rex3(iBase, iIndex, iDstReg),));
|
---|
346 | asLines.append('db 8dh, %#x, %#x'
|
---|
347 | % (x86ModRmMake(iMod, iDstReg, iMemReg), x86SibMake(iBase, iIndex, cShift),));
|
---|
348 | iValue, asAdd = generateDispSib(iValue, iMod, iBase);
|
---|
349 | asLines.extend(asAdd);
|
---|
350 | iValue = (iValue & 0xffff) | (iDstReg_Value & 0xffffffffffff0000);
|
---|
351 |
|
---|
352 | # cmp iDstReg, iValue + jz + int3
|
---|
353 | asLines.extend(cenerateCompareAndCheckSib(sDstReg_Name, iValue, fLoadRestoreRsp));
|
---|
354 |
|
---|
355 | else: # !SIB
|
---|
356 | #
|
---|
357 | # Plain lea reg, [reg] with disp according to iMod,
|
---|
358 | # or lea reg, [disp32] if iMemReg == 5 && iMod == 0.
|
---|
359 | #
|
---|
360 | if (iMemReg & 7) == 5 and iMod == 0:
|
---|
361 | iMemReg_Value = 0;
|
---|
362 | else:
|
---|
363 | iMemReg_Value = g_kaiRegValues[iMemReg];
|
---|
364 |
|
---|
365 | fLoadRestoreRsp = iDstReg == 4;
|
---|
366 |
|
---|
367 | #
|
---|
368 | # 64-bit operand and address size first.
|
---|
369 | #
|
---|
370 | asLines.extend(generateTraceAndLoad(fLoadRestoreRsp, fTracing));
|
---|
371 |
|
---|
372 | # lea
|
---|
373 | asLines.append('db %#x, 8dh, %#x'
|
---|
374 | % (x86RexW3(iMemReg, 0, iDstReg), x86ModRmMake(iMod, iDstReg, iMemReg),));
|
---|
375 | iValue, sValue, asAdd = generateDispModRm(iMemReg_Value, iMod, iMemReg, 0);
|
---|
376 | asLines.extend(asAdd);
|
---|
377 | iValue &= 0xffffffffffffffff;
|
---|
378 |
|
---|
379 | # cmp iDstReg, iValue + jz + int3
|
---|
380 | asLines.extend(generateCompareAndCheckModRm(sDstReg_Name, iValue, sValue, fLoadRestoreRsp));
|
---|
381 |
|
---|
382 |
|
---|
383 | #
|
---|
384 | # 64-bit operand and 32-bit address size.
|
---|
385 | #
|
---|
386 | asLines.extend(generateTraceAndLoad(fLoadRestoreRsp, fTracing));
|
---|
387 |
|
---|
388 | # lea w/ X86_OP_PRF_SIZE_ADDR
|
---|
389 | asLines.append('db 067h, %#x, 8dh, %#x'
|
---|
390 | % (x86RexW3(iMemReg, 0, iDstReg), x86ModRmMake(iMod, iDstReg, iMemReg),));
|
---|
391 | iValue, sValue, asAdd = generateDispModRm(iMemReg_Value, iMod, iMemReg, 1);
|
---|
392 | asLines.extend(asAdd);
|
---|
393 | iValue &= 0x00000000ffffffff;
|
---|
394 |
|
---|
395 | # cmp iDstReg, iValue + jz + int3
|
---|
396 | asLines.extend(generateCompareAndCheckModRm(sDstReg_Name, iValue, sValue, fLoadRestoreRsp));
|
---|
397 |
|
---|
398 |
|
---|
399 | #
|
---|
400 | # 32-bit operand and 64-bit address size.
|
---|
401 | #
|
---|
402 | asLines.extend(generateTraceAndLoad(fLoadRestoreRsp, fTracing));
|
---|
403 |
|
---|
404 | # lea iValue = iMemReg_Value;
|
---|
405 | iValue = iMemReg_Value;
|
---|
406 | if iDstReg >= 8 or iMemReg >= 8:
|
---|
407 | asLines.append('db %#x' % (x86Rex3(iMemReg, 0, iDstReg),));
|
---|
408 | asLines.append('db 8dh, %#x' % (x86ModRmMake(iMod, iDstReg, iMemReg),));
|
---|
409 | iValue, sValue, asAdd = generateDispModRm(iMemReg_Value, iMod, iMemReg, 2);
|
---|
410 | asLines.extend(asAdd);
|
---|
411 | iValue &= 0x00000000ffffffff;
|
---|
412 |
|
---|
413 | # cmp iDstReg, iValue + jz + int3
|
---|
414 | asLines.extend(generateCompareAndCheckModRm(sDstReg_Name, iValue, sValue, fLoadRestoreRsp));
|
---|
415 |
|
---|
416 |
|
---|
417 | #
|
---|
418 | # 16-bit operand and 64-bit address size.
|
---|
419 | #
|
---|
420 | asLines.extend(generateTraceAndLoad(fLoadRestoreRsp, fTracing));
|
---|
421 |
|
---|
422 | # lea
|
---|
423 | asLines.append('db 066h'); # X86_OP_PRF_SIZE_OP
|
---|
424 | if iDstReg >= 8 or iMemReg >= 8:
|
---|
425 | asLines.append('db %#x' % (x86Rex3(iMemReg, 0, iDstReg),));
|
---|
426 | asLines.append('db 8dh, %#x' % (x86ModRmMake(iMod, iDstReg, iMemReg),));
|
---|
427 | iValue, sValue, asAdd = generateDispModRm(iMemReg_Value, iMod, iMemReg, 0, True);
|
---|
428 | asLines.extend(asAdd);
|
---|
429 | iValue = (iValue & 0xffff) | (iDstReg_Value & 0xffffffffffff0000);
|
---|
430 |
|
---|
431 | # cmp iDstReg, iValue
|
---|
432 | asLines.extend(generateCompareAndCheckModRm(sDstReg_Name, iValue, sValue, fLoadRestoreRsp));
|
---|
433 |
|
---|
434 | #
|
---|
435 | # 16-bit operand and 32-bit address size.
|
---|
436 | #
|
---|
437 | asLines.extend(generateTraceAndLoad(fLoadRestoreRsp, fTracing));
|
---|
438 |
|
---|
439 | # lea
|
---|
440 | if random.randint(0, 1):
|
---|
441 | asLines.append('db 066h,067h'); # X86_OP_PRF_SIZE_OP, X86_OP_PRF_SIZE_ADDR
|
---|
442 | else:
|
---|
443 | asLines.append('db 067h,066h'); # X86_OP_PRF_SIZE_ADDR, X86_OP_PRF_SIZE_OP
|
---|
444 | if iDstReg >= 8 or iMemReg >= 8:
|
---|
445 | asLines.append('db %#x' % (x86Rex3(iMemReg, 0, iDstReg),));
|
---|
446 | asLines.append('db 8dh, %#x' % (x86ModRmMake(iMod, iDstReg, iMemReg),));
|
---|
447 | iValue, sValue, asAdd = generateDispModRm(iMemReg_Value, iMod, iMemReg, 0, True);
|
---|
448 | asLines.extend(asAdd);
|
---|
449 | iValue = (iValue & 0xffff) | (iDstReg_Value & 0xffffffffffff0000);
|
---|
450 |
|
---|
451 | # cmp iDstReg, iValue
|
---|
452 | asLines.extend(generateCompareAndCheckModRm(sDstReg_Name, iValue, sValue, fLoadRestoreRsp));
|
---|
453 |
|
---|
454 | oOut.write('\n'.join(asLines));
|
---|
455 | return 0;
|
---|
456 |
|
---|
457 | def main(asArgs):
|
---|
458 | if len(asArgs) != 2 or asArgs[1][0] == '-':
|
---|
459 | print('bs3-cpu-basic-3-high-lea64.py: syntax error!\n', file = sys.stderr);
|
---|
460 | return 2;
|
---|
461 | with open(asArgs[1], 'w', encoding = 'utf-8') as oOut:
|
---|
462 | generateLea64(oOut);
|
---|
463 | return 0;
|
---|
464 |
|
---|
465 | if __name__ == '__main__':
|
---|
466 | sys.exit(main(sys.argv));
|
---|
467 |
|
---|