Assembly 在MASM中将一系列十进制数字转换为十六进制大数

Assembly 在MASM中将一系列十进制数字转换为十六进制大数,assembly,x86,masm,bignum,Assembly,X86,Masm,Bignum,我正在编写一组宏来处理MASM中的大数字,我发现自己需要将一系列数字转换为一个数字。基本上,为了绕过MASM大小限制,我一直将bignum作为字符串传递。因此,一个bignum调用看起来像: MOV_BIG_NUM [eax], <1234567891011121314151617181920212223> 然而,这种方法显然不适用于任意基数。如何将十进制数字的顺序列表转换为十六进制数?您可以执行10的算术乘法和十六进制字符串的数字加法。由此,您可以编写十进制到十六进制字符串的转换

我正在编写一组宏来处理MASM中的大数字,我发现自己需要将一系列数字转换为一个数字。基本上,为了绕过MASM大小限制,我一直将bignum作为字符串传递。因此,一个bignum调用看起来像:

MOV_BIG_NUM [eax], <1234567891011121314151617181920212223>

然而,这种方法显然不适用于任意基数。如何将十进制数字的顺序列表转换为十六进制数?

您可以执行10的算术乘法和十六进制字符串的数字加法。由此,您可以编写十进制到十六进制字符串的转换

C中的插图:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef unsigned uint;

int chhex2val(char ch)
{
  if (ch >= '0' && ch <= '9')
    return ch - '0';
  if (ch >= 'A' && ch <= 'F')
    return ch - 'A' + 10;
  if (ch >= 'a' && ch <= 'f')
    return ch - 'a' + 10;
  abort();
  return 0;
}

char val2chhex(int v)
{
  if (v >= 0 && v < 16)
    return "0123456789ABCDEF"[v];
  abort();
  return '0';
}

// Multiplies a hex string like "17F" by 10 and
// returns a string with the product (e.g. "0EF6").
// The original string isn't modified.
char* mulh10(char* h)
{
  size_t l = strlen(h);
  char* p = malloc(l + 1 + 1);
  size_t i;
  uint c = 0;

  if (p == NULL)
    abort();

  p[l + 1] = '\0';
  for (i = 0; i < l; i++)
  {
    c += chhex2val(h[l - 1 - i]) * 10;
    p[l - i] = val2chhex(c % 16);
    c /= 16;
  }
  p[0] = val2chhex(c);

  return p;
}

// Adds (arithmetically) to a hex string like "17F" a hex/dec digit, e.g. '9'.
// Returns the modified original string (e.g. "188").
char* addhd(char* h, char d)
{
  size_t l = strlen(h);
  size_t i;
  uint c = chhex2val(d);

  for (i = 0; c && i < l; i++)
  {
    c += chhex2val(h[l - 1 - i]);
    h[l - 1 - i] = val2chhex(c % 16);
    c /= 16;
  }

  return h;
}

int main(void)
{
  char num[] = "17F";
  printf("\"17F\" (hex) * 10 = \"%s\" (hex)\n", mulh10(num));
  printf("\"17F\" (hex) + '9' = \"%s\" (hex)\n", addhd(num, '9'));
  printf("\"65535\" (dec) = \"%s\" (hex)\n",
         addhd(mulh10(addhd(mulh10(addhd(mulh10(addhd(mulh10(addhd(mulh10(
         "0"), '6')), '5')), '5')), '3')), '5'));
  return 0;
}

我明白你的意思了。我将尝试在汇编中实现
;foreach digit in list of digits
  ;eax contains the start of memory for the bignum
  IF bit_offset EQ 0 ;Only move a new value in when the offset has just changed
    mov ebx, dword ptr [eax + byte_offset] ;Get the current value at the dword's offset
  ENDIF

  digit = digit SHL bit_offset ;Shift the digit by a certain offset, so that we can store multiple digits in one byte

  or ebx, digit

  bit_offset = bit_offset + 4

  IF bit_offset EQ ( 32 ) ;Number of bits in a dword
    mov dword ptr [eax + byte_offset], ebx ;Move the dword back
    byte_offset = byte_offset + 4 ;Number of bytes in a dword
    bit_offset = 0;
  ENDIF
;end foreach
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef unsigned uint;

int chhex2val(char ch)
{
  if (ch >= '0' && ch <= '9')
    return ch - '0';
  if (ch >= 'A' && ch <= 'F')
    return ch - 'A' + 10;
  if (ch >= 'a' && ch <= 'f')
    return ch - 'a' + 10;
  abort();
  return 0;
}

char val2chhex(int v)
{
  if (v >= 0 && v < 16)
    return "0123456789ABCDEF"[v];
  abort();
  return '0';
}

// Multiplies a hex string like "17F" by 10 and
// returns a string with the product (e.g. "0EF6").
// The original string isn't modified.
char* mulh10(char* h)
{
  size_t l = strlen(h);
  char* p = malloc(l + 1 + 1);
  size_t i;
  uint c = 0;

  if (p == NULL)
    abort();

  p[l + 1] = '\0';
  for (i = 0; i < l; i++)
  {
    c += chhex2val(h[l - 1 - i]) * 10;
    p[l - i] = val2chhex(c % 16);
    c /= 16;
  }
  p[0] = val2chhex(c);

  return p;
}

// Adds (arithmetically) to a hex string like "17F" a hex/dec digit, e.g. '9'.
// Returns the modified original string (e.g. "188").
char* addhd(char* h, char d)
{
  size_t l = strlen(h);
  size_t i;
  uint c = chhex2val(d);

  for (i = 0; c && i < l; i++)
  {
    c += chhex2val(h[l - 1 - i]);
    h[l - 1 - i] = val2chhex(c % 16);
    c /= 16;
  }

  return h;
}

int main(void)
{
  char num[] = "17F";
  printf("\"17F\" (hex) * 10 = \"%s\" (hex)\n", mulh10(num));
  printf("\"17F\" (hex) + '9' = \"%s\" (hex)\n", addhd(num, '9'));
  printf("\"65535\" (dec) = \"%s\" (hex)\n",
         addhd(mulh10(addhd(mulh10(addhd(mulh10(addhd(mulh10(addhd(mulh10(
         "0"), '6')), '5')), '5')), '3')), '5'));
  return 0;
}
"17F" (hex) * 10 = "0EF6" (hex)
"17F" (hex) + '9' = "188" (hex)
"65535" (dec) = "00FFFF" (hex)