From 15ed715e5e809f9af867bcf4469024ee707a339c Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Mon, 1 May 2023 01:23:02 +0100 Subject: Correct the ModR/M cases in x86.c --- src/x86.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/x86.c b/src/x86.c index e33efbb..2cc2d5d 100644 --- a/src/x86.c +++ b/src/x86.c @@ -1,5 +1,5 @@ /* - * Copyright © 2022 Michael Smith + * Copyright © 2023 Michael Smith * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -19,17 +19,18 @@ static int mrm(uchar b, int addrlen) { // I won't lie: I don't *entirely* understand this particular logic. I - // largely based it on some public domain code I found on the internet + // largely based it on some public domain code I found on the internet. + // See: https://github.com/Nomade040/length-disassembler/blob/e8b34546/ldisasm.cpp#L14 + // Bonus route credit goes to Bill for spotting some bugs in prior versions. if (addrlen == 4 || b & 0xC0) { int sib = addrlen == 4 && b < 0xC0 && (b & 7) == 4; switch (b & 0xC0) { // disp8 case 0x40: return 2 + sib; // disp16/32 - case 0: if ((b & 7) == 5) case 0x80: return 1 + addrlen + sib; + case 0: if ((b & 7) != 5) return 1 + sib; + case 0x80: return 1 + addrlen + sib; } - // disp8/32 - if (sib && (b & 7) == 5) return b & 0x40 ? 3 : 6; } if (addrlen == 2 && b == 0x26) return 3; return 1; // NOTE: include the mrm itself in the byte count -- cgit v1.2.3