汇编指令和内联汇编_内联汇编-从头开始

对于C / C ++程序员而言,内联汇编并不是一项新功能,可帮助我们充分利用计算能力。 但是,大多数程序员很少改变这种做法。 实际上,内联汇编仅满足特定的要求,尤其是在涉及高级编程语言的最前沿时。

本文介绍了有关IBM POWER处理器体系结构的两种方案。 使用本文提供的示例,我们可以找出在哪里应用内联汇编。

方案1:一个更好的库

C / C ++编程语言支持逻辑操作。 因此,在该示例中,用户将比特作为基本单位。 用户编写了一种算法来计算一个32位变量占用的位数。

代码A:计算占用的位数

01        inline int bit_taken(int data)
02        {
03        int taken = 0;
04        while (data) {
05         data = (data >> 1);
06         taken++;
07          }
08        return taken;
09        }

该代码显示了使用循环和移位操作。 如果用户以最高优化级别(对于gcc为-O3,对于xlc为-O5)编译代码,则用户可能会发现自动进行了一些优化(例如展开,持续数据传播等)以生成最快的代码世界上的代码。 算法的基本思想虽然没有改变。

清单A: cntlzw的描述

cntlzw(C OU nt下 大号 eadingŽ性爱W¯¯ORD)指令

目的

将源通用寄存器中前导零的数目放入通用寄存器中。

cntlzw指令能够获取前导零的数量。 假设我们有一个数字15,其二进制表示形式是0000、0000、0000、0000、0000、0000、0000、0000、1111, cntlzw会说总共有28个前导零。 重新考虑之后,用户决定简化自己的算法,如代码B所示。

代码B:计算内联汇编所占用的位数

01        #ifdef __ARCH_PPC__
02        inline int bit_taken(int data)
03        {
04        int taken;
05        asm("cntlzw %0, %1\n\t"
06        : "=b" (taken)
07        : "b" (data)
08        );
09        return sizeof(data) * 8 – taken;
10        }
11        #else
...       ...
21        #endif

名为__ARCH_PPC__的宏包装PowerPC体系结构的新代码。 与代码A相比,新代码消除了所有循环或移位。 库提供者的客户可能很高兴看到bit_taken性能有所提高。 它在PowerPC上运行得更快。 而且,应用程序绑定bit_taken甚至可以更好地工作。

这个故事不仅说明用户可以通过丰富的指令改进其算法,而且内联汇编是执行性能工作的最佳助手。 通过将汇编代码嵌入C / C ++,可以最大程度地减少用户在代码更改方面的工作。

方案2:原子比较和交换(CAS)

最近,随着整个计算机行业将重点转移到多处理,多线程上,它不可避免地带来了更多的元素(例如编程中的同步。要在多线程环境中组成信号量和互斥量之类的同步原语,我们经常提到原子操作称为比较交换(CAS)。清单B显示了CAS的伪代码。

清单B:CAS的伪代码

清单1。
compare_and_swap (*p, oldval, newval):
              if (*p == oldval)
          *p = newval;
          success;
              else
                  fail;

在清单B中,首先将内存位置p(* p)的内容与已知值oldval (在当前线程中应为* p的值)进行比较。 仅当它们相同时, 才将newval写入* p。 当另一个线程修改了前面的内存位置时,比较将失败。

为准确起见,应使CAS原子化。 原子性超出了C / C ++的处理能力,但可以通过使用一小段内联汇编代码来保证。 代码C显示了为PowerPC体系结构实现的简单CAS。

代码C:在PowerPC上的简单CAS实现

01        void inline compare_and_swap (volatile int * p, int oldval, int newval)
02        {
03        int fail;
04        __asm__ __volatile__ (
05           "0: lwarx %0, 0, %1\n\t"
06                 "      xor. %0, %3, %0\n\t"
07              " bne 1f\n\t"
08            " stwcx. %2, 0, %1\n\t"
09                 "      bne- 0b\n\t"
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
为了使用汇编语言,必须熟悉CPU和寄存器,还需要掌握CPU的寻址方式。 为了利用NASM进行PC机的汇编语言编程,需要熟悉x86的指令集和NASM汇编程序的若干附加指令。 在使用汇编语言编写的低级代码中,所有的I/O操作(如显示字符和字符串、读入键盘按键、读写磁盘数据等)都是通过调用系统的BIOS(Basic Input Output System,基本输入输出系统)来完成的。 计算机在启动时,因为系统自动装入的引导模块太小(只有一个扇区,512个字节),一般只能包含装载操作系统启动程序的代码,而启动程序本身的代码,则必须放在磁盘的其他地方。至于操作系统的大量代码,一般用C语言和汇编语言混合编写,保存为磁盘文件后,再由启动程序装载入内存。 DOS和Windows的COM可执行文件简单小巧,可用于引导代码的运行测试。 为了调试我们编写的汇编语言程序,可以使用传统小巧的实模式调试工具debug。 这次实验,我们先介绍CPU及其寄存器和寻址方法;再给出常用的x86指令和NASM汇编程序的常用附加指令;接着列出几个常用的BIOS中断及其调用方法;然后编写一个读入按键并回显字符到屏幕的小汇编程序MY-OS,并将其作为另一个引导程序;其后,把MY-OS的代码放到第二个物理扇区,再编写装载此代码块的汇编程序放到引导扇区;接着介绍COM可执行文件的生成和使用,最后简介实模式调试工具debug的基本使用方法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值