C语言中的按位运算(0x80、0xFF、<<)

2023-12-31

我在理解这段代码时遇到问题。我所知道的是,我们已将代码传递到汇编器中,该汇编器已将代码转换为“字节代码”。现在我有一个虚拟机应该可以读取这段代码。该函数应该读取第一个字节代码指令。我不明白这段代码中发生了什么。我想我们正在尝试读取这个字节码,但不明白它是如何完成的。

static int32_t  bytecode_to_int32(const uint8_t *bytecode, size_t size)
{
    int32_t result;
    t_bool  sign;
    int     i;

    result = 0;
    sign = (t_bool)(bytecode[0] & 0x80);
    i = 0;
    while (size)
    {
        if (sign)
            result += ((bytecode[size - 1] ^ 0xFF) << (i++ * 8));
        else
            result += bytecode[size - 1] << (i++ * 8);
        size--;
    }
    if (sign)
        result = ~(result);
    return (result);
}

这段代码写得有些糟糕,一行中有很多操作,因此包含各种潜在的错误。它看起来很脆。

  • bytecode[0] & 0x80只需读取 MSB 符号位,假设它是 2 的补码或类似的,然后将其转换为布尔值。
  • 该循环从最高有效字节向后迭代到最低有效字节。
  • 如果符号为负,代码将执行数据字节与 0xFF 的异或。基本上反转数据中的所有位。 XOR 的结果是int.
  • 然后数据字节(或上述 XOR 的结果)被移位i * 8位向左。数据总是隐式提升为int,所以万一i * 8碰巧给出的结果大于INT_MAX,这里有一个巨大的未定义行为错误。转换为更安全的做法uint32_t在移位之前,进行移位,然后转换为有符号类型。
  • 所结果的int被转换为int32_t- 这些可以是相同类型或不同类型,具体取决于系统。
  • i 加 1,size 减 1。
  • 如果符号为负,则int32_t被反转为符号扩展的某个 2 的补码负数,并且所有数据位再次反转。除了通过左移移入的所有零也被替换为 1。这是有意还是无意,我无法判断。例如,如果你从类似的事情开始0x0081你现在有类似的东西0xFFFF01FF。我不知道这种格式有何意义。

我的看法是bytecode[size - 1] ^ 0xFF(这相当于~)用于切换数据位,以便稍后在以下情况下切换回其原始值:~稍后调用。一名程序员has用评论记录这些技巧,如果它们接近能力的话。


无论如何,不​​要使用此代码。如果目的只是交换 4 字节整数的字节顺序(字节序),则必须从头开始重写此代码。

正确的做法是:

static int32_t big32_to_little32 (const uint8_t* bytes)
{
  uint32_t result = (uint32_t)bytes[0] << 24 | 
                    (uint32_t)bytes[1] << 16 | 
                    (uint32_t)bytes[2] <<  8 | 
                    (uint32_t)bytes[3] <<  0 ; 

  return (int32_t)result;
}

任何比上述更复杂的代码都是高度可疑的代码。我们不必担心符号是特殊情况,上面的代码保留了原始的符号格式。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言中的按位运算(0x80、0xFF、<<) 的相关文章

随机推荐

  • 使用 github 操作创建拉取请求

    我试图让它发挥作用 但我也很困惑 在触发彼得埃文斯公关之前 它之间缺少什么 这个场景非常简单 我喜欢在任何 feature 分支上推送 自动创建 PR 但相反 我遇到了奇怪的场景 其中开发更改应用于 feature 分支之上 有人可以给我提
  • 为什么使用 webflux 进行 Spring Boot 测试会忽略自定义 Jackson 模块

    我正在使用 Spring Boot 2 0 1 和 WebFlux 路由器功能编写一个应用程序 not基于注释 对于我的一些数据对象 我编写了扩展的自定义序列化器StdSerializer 这些我注册在SimpleModule并将该模块公开
  • 隐藏溢出时检测用户滚动尝试

    scroll 当内容为overflow hidden wheel 滚轮鼠标会触发 但鼠标不会触发魔术触控板 http www apple com shop product MC380LL A magic trackpad or 魔术鼠标 h
  • SQL - 检查列是否自动递增

    我正在尝试运行查询来检查列是否自动递增 我可以检查类型 默认值 是否可为空等 但我不知道如何测试它是否自动递增 这是我测试其他事情的方法 SELECT FROM INFORMATION SCHEMA COLUMNS WHERE TABLE
  • InfluxDB - 仅获取查询中的最后一个值

    是否可以只查询查询结果的最后一个值 或第n个值 例如 在查询中 SELECT value FROM response times WHERE time gt now 1h limit 1000 是否有可能只获取最后一个值 即时间上更早的值
  • Django 管理表单 - 如何动态更改选择选项?

    我有 2 个型号 class City models Model name models CharField max length 50 slug models SlugField max length 50 class CityNews
  • 批处理文件中括号内的转义括号

    这就是我正在尝试做的 echo This is some code that is echo Important to echo exactly as is echo Even if I use parenthesis echo for s
  • CesiumViewer 中的响应式 DIV [CesiumJS]

    我正在定制一个 Cesium 地图 它有一个覆盖层 里面有各种信息 我用 bootsrap 实现的覆盖层的样式 不幸的是我放置的 div 保留在特定位置并忽略页面大小的调整 有没有办法让添加到铯查看器的 DIV 响应 我现在做的是 var
  • 为什么我的代码没有在我的应用程序上更新? (更新eclipse后)

    在你因为看不到任何代码而否决我的问题 否决的荒谬理由 之前 请阅读它 问题 问题是 即使我更改代码并在手机上运行它 它也会运行 但应用程序实际上不会改变 例如 如果我以前吃吐司会说 hello world 在 onCreate 中 但后来我
  • 什么是 Webhook?我为什么要关心?

    我能找到的最好的是这个维基条目 http en wikipedia org wiki Webhook 我想 肯定还有比这更多的事情 我错过了什么吗 来自doc https webhooks pbworks com w page 133851
  • 如何获得所有可能的 3 个字母排列? [复制]

    这个问题在这里已经有答案了 可能的重复 列出字符串 整数的所有排列 https stackoverflow com questions 756055 listing all permutations of a string integer
  • Pandas diff SeriesGroupBy 比较慢

    Total time 1 01876 s Function prepare at line 91 Line Hits Time Per Hit Time Line Contents 91 profile 92 def prepare 93
  • 远程连接mysql

    我安装了 Windows 7vm一样的pc 我有一个包含以下代码的表单 MySqlConnection connection new MySqlConnection SERVER 127 0 0 1 DATABASE my test UID
  • Keras:ValueError:检查模型目标时出错:预期密集_1 具有形状(无,10),但得到形状为(10,1)的数组

    我是 keras 新手 遇到此错误 ValueError 检查模型目标时出错 预期 dend 1 具有形状 None 10 但得到形状为 10 1 的数组 我的输入数组形状是 10 1010 我的模型只有一层 model Sequentia
  • SonarQube 与 Jest 单元测试

    我一直在尝试找出如何填充声纳Qube和我的笑话单元测试和 net 单元测试 我有一个本地版本SQ 6 7以及所有最新版本的 Javascript 和 C 插件 说到 Jest 我有sonar jest reporter https www
  • 模拟框架集分隔符行为

    HTML5 当前规范删除了 tag 有一个很好的功能没有它就不容易重现 在框架集中 您可以使用鼠标更改框架分隔线的位置 如何在 JavaScript 中使用 DIV 提供相同的功能 我遇到过下列 http www jsfiddle net
  • React.memo 如何与 useCallback 配合使用

    据我了解 React memo 是一个记忆组件的 API 如果它的 props 没有改变 React 使用该组件的最新渲染 而不将其与之前的版本进行比较 跳过新渲染并与旧渲染进行比较可以加快应用程序的速度 凉爽的 现在 这是我不明白的 如果
  • Java orElse 的可选工作并不像 else

    在Optional中 当调用optimal orElse方法时 无论元素是否存在 orElse部分是否被执行 它都不会表现为if else条件 在下面的代码中 如果您看到Case 1getNullPoJo 和 getDefaultPoJo
  • Google Maps Android api v2 折线长度

    我正在尝试找到 android 地图 api v2 方法 该方法将确定我在移动时创建的折线的长度 我会将其放入 onLocationChanged 中以进行持续更新 有人知道地图 api 的方法是什么以及显示长度的单位是什么吗 Polyli
  • C语言中的按位运算(0x80、0xFF、<<)

    我在理解这段代码时遇到问题 我所知道的是 我们已将代码传递到汇编器中 该汇编器已将代码转换为 字节代码 现在我有一个虚拟机应该可以读取这段代码 该函数应该读取第一个字节代码指令 我不明白这段代码中发生了什么 我想我们正在尝试读取这个字节码