@@ -423,7 +423,7 @@ export class Instruction extends Statement
423423 else if ( op . rm !== null )
424424 {
425425 let extraRex ;
426- [ extraRex , modRM , sib ] = this . makeModRM ( op . rm , op . reg ) ;
426+ [ extraRex , modRM , sib ] = this . makeModRM ( op . rm , op . reg , op . dispMul !== null ? 32 : null ) ;
427427 if ( extraRex !== 0 )
428428 rexVal |= extraRex , prefsToGen . REX = true ;
429429 }
@@ -437,6 +437,8 @@ export class Instruction extends Statement
437437 prefsToGen . DATASIZE = true ;
438438
439439 // Time to generate!
440+ let modRmIndex = 0 ;
441+
440442 if ( prefsToGen . SEG0 ) this . genByte ( 0x26 ) ;
441443 if ( prefsToGen . SEG1 ) this . genByte ( 0x2E ) ;
442444 if ( prefsToGen . SEG2 ) this . genByte ( 0x36 ) ;
@@ -470,10 +472,12 @@ export class Instruction extends Statement
470472 this . genByte ( opcode >> 8 ) ;
471473 }
472474 this . genByte ( opcode ) ;
473- if ( modRM !== null )
475+ if ( modRM !== null ) {
476+ modRmIndex = this . length ;
474477 this . genByte ( modRM ) ;
475- if ( sib !== null )
476- this . genByte ( sib ) ;
478+ if ( sib !== null )
479+ this . genByte ( sib ) ;
480+ }
477481
478482 // Generating the displacement
479483 if ( op . rm ?. value ?. addend != null )
@@ -493,12 +497,16 @@ export class Instruction extends Statement
493497 } ) ) ;
494498 this . ipRelative = true ;
495499 }
496- this . genValue ( value , {
500+ const finalSize = this . genValue ( value , {
497501 size : op . rm . dispSize || 32 ,
498502 signed : true ,
499503 sizeRelative,
500504 dispMul : op . dispMul
501505 } ) ;
506+ if ( op . rm . dispSize != finalSize ) {
507+ op . rm . dispSize = finalSize ;
508+ this . bytes [ modRmIndex ] = this . makeModRM ( op . rm , op . reg , finalSize ) [ 1 ] ;
509+ }
502510 }
503511 if ( op . relImm !== null )
504512 this . genValue ( op . relImm . value , { size : op . relImm . size , sizeRelative : true , functionAddr : true } ) ;
@@ -513,24 +521,22 @@ export class Instruction extends Statement
513521
514522 /** Generate the ModRM byte
515523 * @param {Operand } rm
516- * @param {Operand } r */
517- makeModRM ( rm , r )
518- {
524+ * @param {Operand } r
525+ * @param { int? } forcedDispSize */
526+ makeModRM ( rm , r , forcedDispSize ) {
519527 let modrm = 0 , rex = 0 , sib = null ;
520528 // rm's and r's values may be edited, however the objects themselves shouldn't be modified
521529 let rmReg = rm . reg , rmReg2 = rm . reg2 , rReg = r . reg ;
522530
523531 // Encoding the "reg" field
524- if ( rReg >= 8 )
525- {
532+ if ( rReg >= 8 ) {
526533 rex |= 4 ; // rex.R extension
527534 rReg &= 7 ;
528535 }
529536 modrm |= rReg << 3 ;
530537
531538 // Special case for RIP-relative addressing
532- if ( rm . ripRelative )
533- {
539+ if ( rm . ripRelative ) {
534540 rm . value . addend = rm . value . addend || 0n ;
535541 // mod = 00, reg = (reg), rm = 101
536542 return [ rex , modrm | 5 , null ] ;
@@ -539,19 +545,20 @@ export class Instruction extends Statement
539545 // Encoding the "mod" (modifier) field
540546 if ( ! rm . type . isMemory )
541547 modrm |= 0xC0 ; // mod=11
542- else if ( rmReg >= 0 )
543- {
544- if ( rm . value . addend != null )
545- {
546- this . determineDispSize ( rm , 8 , 32 ) ;
548+ else if ( rmReg >= 0 ) {
549+ if ( rm . value . addend != null ) {
550+ if ( forcedDispSize != null )
551+ rm . dispSize = forcedDispSize ;
552+ else
553+ this . determineDispSize ( rm , 8 , 32 ) ;
554+
547555 if ( rm . dispSize == 8 )
548556 modrm |= 0x40 ; // mod=01
549557 else
550558 modrm |= 0x80 ; // mod=10
551559 }
552560 }
553- else // mod = 00
554- {
561+ else { // mod = 00
555562 // These are the respective "none" type registers
556563 rmReg = 5 ;
557564 if ( currBitness == 64 && rmReg2 < 0 )
@@ -567,12 +574,10 @@ export class Instruction extends Statement
567574 modrm |= rmReg2 < 0 ? rmReg : 4 ;
568575
569576 // Encoding an SIB byte if necessary
570- if ( ( modrm & 0xC0 ) != 0xC0 && ( modrm & 7 ) == 4 ) // mod!=11, rm=100 signifies an SIB byte follows
571- {
577+ if ( ( modrm & 0xC0 ) != 0xC0 && ( modrm & 7 ) == 4 ) { // mod!=11, rm=100 signifies an SIB byte follows
572578 if ( rmReg2 < 0 )
573579 rmReg2 = 4 ; // indicating the "none" index
574- else if ( rmReg2 >= 8 )
575- {
580+ else if ( rmReg2 >= 8 ) {
576581 rex |= 2 ; // rex.X extension
577582 rmReg2 &= 7 ;
578583 }
0 commit comments