WebAssembly 入门课
于航
PayPal 高级软件工程师
10751 人已学习
新⼈⾸单¥29
登录后,你可以任选4讲全文学习
课程目录
已完结/共 23 讲
结束语 (1讲)
WebAssembly 入门课
15
15
1.0x
00:00/00:00
登录|注册

05 | 二进制编码:WebAssembly 微观世界的基本数据规则是什么?

你好,我是于航。
在上节课的最后,我举了一个简单的例子,来帮助你理解了 Wasm 二进制模块内部字节码的基本结构。在这短短的几十个十六进制数字中,我们看到了组成 Wasm 模块所不可或缺的“魔数”与“版本号”编码,以及组成了各个 Section 结构的专有编码。
在这些字节码中,Wasm 会使用不同的编码方案来处理不同的字段数据。比如对于 Section 的通用头部结构来说,Wasm 会用名为 “varuint7” 的编码方式,来编码各个 Section 的专有 ID。
除此之外,对于字符串以及浮点数,Wasm 也会分别通过 UTF-8 以及 IEEE-754 编码来将这些字面量值转换为对应的二进制编码,并存储到最终的 Wasm 二进制模块文件中。
那么本节课,我们就来一起看看 Wasm 所使用的这些数据编码方式,它们决定了 Wasm 在二进制层面的具体数据存储规则。

字节序

首先,作为字节码组成方式最为重要的一个特征,我们来聊一聊与具体编码方案无关的另外一个话题 —— 字节序。
那么什么是“字节序”呢?相信仅从字面上理解,你就能够略知一二。字节序也就是指“字节的排列顺序”。在计算机中,数据是以最原始的二进制 0 和 1 的方式被存储的。在大多数现代计算机体系架构中,计算机的最小可寻址数据为 8 位(bit),即 1 个字节(byte)。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

WebAssembly(Wasm)是一种用于在Web浏览器中运行高性能应用程序的二进制指令集。本文介绍了Wasm二进制模块内部字节码的基本结构和数据编码方式。文章首先讨论了字节序,即数据在内存中的存储顺序,包括小端模式和大端模式。接着介绍了LEB-128编码,这是一种基于小端模式的可变长编码,用于编码无符号整数和有符号整数。通过具体的编码示例,详细解释了LEB-128编码的规则和过程。此外,文章还介绍了IEEE-754浮点数编码的具体方式,以及UTF-8字符串编码的过程。这些内容有助于读者了解Wasm在二进制层面的数据存储规则,为理解Wasm的内部结构和实现原理提供了基础知识。 Wasm使用不同的编码方式来编码其内部使用到的各类字面量数据,如整数值、浮点数值和字符串值。这些值可能被用于指令立即数、指令OpCode和Section组成结构等Wasm二进制模块的各个部分中。对于整数,Wasm使用LEB-128编码方式来编码具有不同长度和符号性的字面量整数值;对于浮点数,Wasm使用IEEE-754标准进行编码;而对于字符串,Wasm采用了UTF-8编码。通过编码,各数字值类型能够按照最合适的格式被摆放在Wasm的二进制字节码序列中。文章还提到了Wasm内部使用的数字值类型,如uintN、varuintN和varintN,以及它们的取值范围和编码方式。最后,文章留下了一个练习题,要求读者计算有符号数“-654321”在varint32类型下的可能编码值。这篇文章通过简洁明了的方式介绍了Wasm的数据编码方式,为读者快速了解Wasm的内部数据存储规则提供了指导。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《WebAssembly 入门课》
新⼈⾸单¥29
立即购买
登录 后留言

全部留言(8)

  • 最新
  • 精选
  • 替换出 UTF-8 编码对应的三个字节。在替换时,你需要将从上一步获得的二进制序列中的各个二进制位,按照从左到右的顺序依次替换掉 UTF-8 编码中用于占位的 “x” ======================= 这一步是怎么替换的? 没有看明白的 01100111 10000001 ---> 11100110 10011110 10000001

    作者回复: 首先,我们根据码位值找到表中的一个范围 [U+0800, U+FFFF]。然后这个范围对应着一个模板 “1110xxxx 10xxxxxx 10xxxxxx”,其中就有占位的 “x”。然后你再把上面的 “01100111 10000001” 从左到右按位依次替换到模板中的 “x”,就可以得到结果了。

    2020-09-16
    8
  • Geek_58a18e
    大学没学懂的知识 工作好几年后配上老师的教程 醍醐灌顶 感谢

    作者回复: 很高兴能够帮到你 :)

    2020-09-27
    2
  • 为什么要有那么多编码方式呢? 虽说每种编码方式都是针对的场景,但是还是没有个整体的概念。 要不老师来个加餐讲讲各种编码方式出现的历史背景和要解决的问提? 期待

    作者回复: 收到你的反馈哈,会考虑的。其实对于编码你可以这样简单理解:人们通常都喜欢与文本打交道,比如字母、字符,甚至汉字等等。但是计算机只能跟 “1” 和 “0” 打交道。而“编码”就是为了将这些人类可读的“文本”依据某种规则和方式转换为 “1” 和 “0” 的序列这样的一个过程。

    2020-09-16
    2
    2
  • Twittytop
    ”其左侧填充指定的二进制位来增加整个有符号数的总位数,并同时保证该二进制数本身的值不会被改变。“这句话中并同时保证该二进制数本身的值不会被改变是什么意思?是说左侧填充了符号位之后本身的值没改变?好像不对,还是左侧位填充1,其他的不变? 另外为什么要是7的倍数,是这个编码方式就是这么规定的吗?

    作者回复: 1. 这里我们做的实际上就是“符号扩展”,按照最高位符号位的情况来进行位填充。也就是如果符号位是 1,那就填充 1,否则填充 0。这样就可以保证填充后整个数字的值不会发生改变。 2. 是的。实际上这里的 7 是跟 LEB128 的编码规则有关的,2^7 也就是 128。

    2022-04-25
  • AIGC Weekly 周报
    有符号数 “-654321” 在 varint32 类型下的可能编码值之一是:0x58、0x88、0x8f。 想请问一下老师,如果出现了占位的 0x80 或 0xff 应该怎么计算呢?有知道的小伙伴也可以说下,谢谢!

    作者回复: 你的问题是说从含有填充字节的编码值计算原值?

    2021-12-05
    2
  • champ
    -654321 原码: 1 1001 1111 1011 1111 0001 反码: 1 0110 0000 0100 0000 1110 补码: 1 0110 0000 0100 0000 1111 符号扩展:(无需扩展) 1 0110 0000 0100 0000 1111 分组: 1011000 0001000 0001111 填充: 01011000 10001000 10001111 16进制表示: 0x58 0x88 0x8f
    2021-01-17
    1
    5
  • vividlipi
    第一步: -654321:第一个1表示符号位,补码表示是:101100000010000001111 第二步: 有符号拓展扩展到7的倍数: 1011000 0001000 0001111 第三步: 分组填充: 01011000 10001000 10001111 第四步: 0x58 0x88 0x8f
    2020-10-03
    2
  • becky
    除了0x58 0x88 0x8f,“-654321”是也可以将数字值扩展为32位后再编码吧,编码后是0x7f 0xff 0xd8 0x88 0x8f
    2023-08-11归属地:浙江
    1
收起评论
显示
设置
留言
8
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部