如何将多个8位字块转换为一个数字?

低频

首先,我知道如果我有一台8位计算机,它只能处理8位数字,但不能超过8位,但是我知道仍然可以表示16位数字甚至32,64,128-通过在ram中分配更多的内存来获得位数。但是为了简单起见,我们仅以16位数字为例。

假设我们在ram中有一个16位数字,如下所示:

12 34 <-- That's Hexadecimal btw

让我们也以二进制形式编写它,以防万一您偏爱二进制形式:

00010010 00110100 <-- Binary
              &
      4660 in decimal

现在,我们知道计算机无法将这个大数字(4660)理解为一个数字,因为计算机只能理解8位数字,最高只能达到255。因此右侧的字节将保持不变:

00110100 <-- 52 in decimal

但左字节:

00010010 <-- would be 18 if it was the byte on the right, 
             but since it is on the left, it means that its
             4608 

所以我的问题是,如果计算机只能理解小于255的数字,那么计算机如何读取第二个字节为4608,然后如何将这两个字节解释为单个数字(4660)?

谢谢,如果您感到困惑,请随时在评论中问我。我说得越清楚越好。

光谱

好吧,这是比硬件体系结构更多的编程问题,因为在您的测试用例中CPU仅执行8位操作,而对16位则一无所知。您的示例是:在8位ALU上进行16位算术运算,通常是通过将数字的高半部分和低半部分拆分(然后将其相加)来完成的。这可以通过更多的方式来完成,例如以下几种(使用C ++):

  1. 转移

    const int _h=0; // MSB location
    const int _l=1; // LSB location
    BYTE h,l; // 8 bit halves
    WORD hl;  // 16 bit value
    h=((BYTE*)(&hl))[_h];
    l=((BYTE*)(&hl))[_l];
    // here do your 8bit stuff on h,l
    ((BYTE*)(&hl))[_h]=h;
    ((BYTE*)(&hl))[_l]=l;
    

    您需要从8bit / 16bit的“寄存器”副本中复制或复制,这很慢,但有时可以减轻麻烦。

  2. 指针

    const int _h=0; // MSB location
    const int _l=1; // LSB location
    WORD hl;  // 16 bit value
    BYTE *h=((BYTE*)(&hl))+_h;
    BYTE *l=((BYTE*)(&hl))+_l;
    // here do your 8bit stuff on *h,*l or h[0],l[0]
    

    你不需要复制任何东西,但使用指针访问*h,*l代替h,l指针初始化仅完成一次。

  3. 联盟

    const int _h=0; // MSB location
    const int _l=1; // LSB location
    union reg16 
     {
     WORD dw;  // 16 bit value
     BYTE db[2]; // 8 bit values
     } a;
    // here do your 8bit stuff on a.db[_h],a.db[_l]
    

    #2相同,但形式更易于管理

  4. CPU 8/16位寄存器

    即使是8位CPU,通常也可以通过一半或全部寄存器访问16位寄存器。例如,在Z80上,AF,BC,DE,HL,PC,SP还可以通过其半寄存器直接访问其中的大多数。因此,有使用说明的说明hl,也有h,l单独使用说明的说明在x86上它是相同的,例如:

    mov AX,1234h
    

    与以下内容相同(除了计时和可能的代码长度):

    mov AH,12h
    mov AL,34h
    

简而言之,这就是8/16位之间的转换,但我想您是在询问有关如何完成操作的更多信息。这可以通过使用Carry标志来完成(可悲的是,大多数高级语言都缺少汇编器)。例如,在8位ALU(x86体系结构)上进行16位加法是这样的:

// ax=ax+bx
add al,bl
adc ah,bh

因此,首先添加最低的BYTE,然后添加最高的+ Carry有关更多信息,请参见:

有关如何实现其他操作的更多信息,请参见关于bignum算术的任何实现。

[Edit1]

这是一个仅用8位算术即可打印16位数字的小型C ++示例。您可以将8位ALU用作构建块,以进行N*816位操作的相同方式进行位操作...

//---------------------------------------------------------------------------
// unsigned 8 bit ALU in C++
//---------------------------------------------------------------------------
BYTE cy;                    // carry flag cy = { 0,1 }
void inc(BYTE &a);          // a++
void dec(BYTE &a);          // a--
BYTE add(BYTE a,BYTE b);    // = a+b
BYTE adc(BYTE a,BYTE b);    // = a+b+cy
BYTE sub(BYTE a,BYTE b);    // = a-b
BYTE sbc(BYTE a,BYTE b);    // = a-b-cy
void mul(BYTE &h,BYTE &l,BYTE a,BYTE b);    // (h,l) = a/b
void div(BYTE &h,BYTE &l,BYTE &r,BYTE ah,BYTE al,BYTE b);   // (h,l) = (ah,al)/b ; r = (ah,al)%b
//---------------------------------------------------------------------------
void inc(BYTE &a) { if (a==0xFF) cy=1; else cy=0; a++; }
void dec(BYTE &a) { if (a==0x00) cy=1; else cy=0; a--; }
BYTE add(BYTE a,BYTE b)
    {
    BYTE c=a+b;
    cy=DWORD(((a &1)+(b &1)   )>>1);
    cy=DWORD(((a>>1)+(b>>1)+cy)>>7);
    return c;
    }
BYTE adc(BYTE a,BYTE b)
    {
    BYTE c=a+b+cy;
    cy=DWORD(((a &1)+(b &1)+cy)>>1);
    cy=DWORD(((a>>1)+(b>>1)+cy)>>7);
    return c;
    }
BYTE sub(BYTE a,BYTE b)
    {
    BYTE c=a-b;
    if (a<b) cy=1; else cy=0;
    return c;
    }
BYTE sbc(BYTE a,BYTE b)
    {
    BYTE c=a-b-cy;
    if (cy) { if (a<=b) cy=1; else cy=0; }
    else    { if (a< b) cy=1; else cy=0; }
    return c;
    }
void mul(BYTE &h,BYTE &l,BYTE a,BYTE b)
    {
    BYTE ah,al;
    h=0; l=0; ah=0; al=a;
    if ((a==0)||(b==0)) return;
    // long binary multiplication
    for (;b;b>>=1)
        {
        if (BYTE(b&1))
            {
            l=add(l,al);    // (h,l)+=(ah,al)
            h=adc(h,ah);
            }
        al=add(al,al);      // (ah,al)<<=1
        ah=adc(ah,ah);
        }
    }
void div(BYTE &ch,BYTE &cl,BYTE &r,BYTE ah,BYTE al,BYTE b)
    {
    BYTE bh,bl,sh,dh,dl,h,l;
    // init
    bh=0; bl=b; sh=0;   // (bh,bl) = b<<sh so it is >= (ah,al) without overflow
    ch=0; cl=0; r=0;    // results = 0
    dh=0; dl=1;         // (dh,dl) = 1<<sh
    if (!b) return;     // division by zero error
    if ((!ah)&&(!al)) return;   // division of zero
    for (;bh<128;)
        {
        if (( ah)&&(bh>=ah)) break;
        if ((!ah)&&(bl>=al)) break;
        bl=add(bl,bl);
        bh=adc(bh,bh);
        dl=add(dl,dl);
        dh=adc(dh,dh);
        sh++;
        }
    // long binary division
    for (;;)
        {
        l=sub(al,bl);   // (h,l) = (ah,al)-(bh,bl)
        h=sbc(ah,bh);
        if (cy==0)      // no overflow
            {
            al=l; ah=h;
            cl=add(cl,dl);  // increment result by (dh,dl)
            ch=adc(ch,dh);
            }
        else{           // overflow -> shoft right
            if (sh==0) break;
            sh--;
            bl>>=1;     // (bh,bl) >>= 1
            if (BYTE(bh&1)) bl|=128;
            bh>>=1;
            dl>>=1;     // (dh,dl) >>= 1
            if (BYTE(dh&1)) dl|=128;
            dh>>=1;
            }
        }
    r=al;       // remainder (low 8bit)
    }
//---------------------------------------------------------------------------
// print 16bit dec with 8bit arithmetics
//---------------------------------------------------------------------------
AnsiString prn16(BYTE h,BYTE l)
    {
    AnsiString s="";
    BYTE r; int i,j; char c;
    // divide by 10 and print the remainders
    for (;;)
        {
        if ((!h)&&(!l)) break;
        div(h,l,r,h,l,10);  // (h,l)=(h,l)/10; r=(h,l)%10;
        s+=char('0'+r);         // add digit to text
        }
    if (s=="") s="0";
    // reverse order
    i=1; j=s.Length();
    for (;i<j;i++,j--) { c=s[i]; s[i]=s[j]; s[j]=c; }
    return s;
    }
//---------------------------------------------------------------------------

我使用VCL AnsiString进行文本存储,您可以将其更改为字符串,甚至char[]改为字符串您需要除以BYTE的整数,然后将整数除。查看该div功能的工作原理。此处为264打印的最低有效位的示例264%10...

a = 264 = 00000001 00001000 bin
b =  10 = 00000000 00001010 bin
d =   1 = 00000000 00000001 bin
// apply shift sh so b>=a 
a = 00000001 00001000 bin
b = 00000001 01000000 bin
d = 00000000 00100000 bin
sh = 5
// a-=b c+=d while a>=b
// a<b already so no change
a = 00000001 00001000 bin b = 00000001 01000000 bin c = 00000000 00000000 bin d = 00000000 00100000 bin
// shift right
b = 00000000 10100000 bin d = 00000000 00010000 bin sh = 4
// a-=b c+=d while a>=b
a = 00000000 01101000 bin c = 00000000 00010000 bin
// shift right
b = 00000000 01010000 bin d = 00000000 00001000 bin sh = 3
// a-=b c+=d while a>=b
a = 00000000 00011000 bin c = 00000000 00011000 bin
// shift right
b = 00000000 00101000 bin d = 00000000 00000100 bin sh = 2
b = 00000000 00010100 bin d = 00000000 00000010 bin sh = 1
// a-=b c+=d while a>=b
a = 00000000 00000100 bin c = 00000000 00011010 bin
// shift right
b = 00000000 00001010 bin d = 00000000 00000001 bin sh = 0
// a<b so stop a is remainder -> digit = 4
//now a=c and divide again from the start to get next digit ...

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何将列转换为以另一个数字列中的值为条件的和?

来自分类Dev

如何将一个数组转换为Java中的一个链表

来自分类Dev

如何将数字转换为R中另一个数字的第一个整除数

来自分类Dev

如何将两个列表转换为一个数据列表,将一个列表转换为一个数据框?

来自分类Dev

将8位字符串转换为16个字的块序列

来自分类Dev

将8位字符串转换为16个字的块序列

来自分类Dev

如何将多个视频一个接一个地转换为AVI

来自分类Dev

如何将两个十六进制数字合并为一个数字,然后将其转换为十进制。

来自分类Dev

如何将一个数据框转换为另一个数据框

来自分类Dev

如何将多维数组转换为一个数组?Javascript

来自分类Dev

如何使用Arduino将数字从一个数字范围转换为另一个数字范围

来自分类Dev

如何将64位数字转换为8位

来自分类Dev

如何将八位字节字符串转换为数字?

来自分类Dev

Python:如何将具有多个数字的多个列表转换为数组?

来自分类Dev

如何将两个数据帧转换为另一个数据帧?

来自分类Dev

如何将数字转换为3位数字

来自分类Dev

将位从一个数组转换为另一个数组?

来自分类Dev

如何将UTF-8字节块转换为字符?

来自分类Dev

如何将一个日期的varchar(6)转换为char(8)

来自分类Dev

如何将几个 IF 转换为一个 LOOP

来自分类Dev

将单个索引的多个数组转换为一个数组

来自分类Dev

使用 Node JS 将多个数组转换为对象到一个数组

来自分类Dev

将一个数字转换为另一个由 9 组成的数字

来自分类Dev

如何将方解石逻辑计划转换为另一个数据引擎的物理计划?

来自分类Dev

如何将一个数据框列直接转换为以列值作为列索引的数据框?

来自分类Dev

如何将字符串转换为数组到新的另一个数组?

来自分类Dev

如何将列表的元素转换为单个数字

来自分类Dev

将数组中的数字转换为另一个数组

来自分类Dev

如何将数字的格式复制到另一个数字?

Related 相关文章

  1. 1

    如何将列转换为以另一个数字列中的值为条件的和?

  2. 2

    如何将一个数组转换为Java中的一个链表

  3. 3

    如何将数字转换为R中另一个数字的第一个整除数

  4. 4

    如何将两个列表转换为一个数据列表,将一个列表转换为一个数据框?

  5. 5

    将8位字符串转换为16个字的块序列

  6. 6

    将8位字符串转换为16个字的块序列

  7. 7

    如何将多个视频一个接一个地转换为AVI

  8. 8

    如何将两个十六进制数字合并为一个数字,然后将其转换为十进制。

  9. 9

    如何将一个数据框转换为另一个数据框

  10. 10

    如何将多维数组转换为一个数组?Javascript

  11. 11

    如何使用Arduino将数字从一个数字范围转换为另一个数字范围

  12. 12

    如何将64位数字转换为8位

  13. 13

    如何将八位字节字符串转换为数字?

  14. 14

    Python:如何将具有多个数字的多个列表转换为数组?

  15. 15

    如何将两个数据帧转换为另一个数据帧?

  16. 16

    如何将数字转换为3位数字

  17. 17

    将位从一个数组转换为另一个数组?

  18. 18

    如何将UTF-8字节块转换为字符?

  19. 19

    如何将一个日期的varchar(6)转换为char(8)

  20. 20

    如何将几个 IF 转换为一个 LOOP

  21. 21

    将单个索引的多个数组转换为一个数组

  22. 22

    使用 Node JS 将多个数组转换为对象到一个数组

  23. 23

    将一个数字转换为另一个由 9 组成的数字

  24. 24

    如何将方解石逻辑计划转换为另一个数据引擎的物理计划?

  25. 25

    如何将一个数据框列直接转换为以列值作为列索引的数据框?

  26. 26

    如何将字符串转换为数组到新的另一个数组?

  27. 27

    如何将列表的元素转换为单个数字

  28. 28

    将数组中的数字转换为另一个数组

  29. 29

    如何将数字的格式复制到另一个数字?

热门标签

归档