【问题标题】:Insertion Sort of uint16_t halfwords?uint16_t 半字的插入排序?
【发布时间】:2023-03-09 19:20:01
【问题描述】:

这是对整个带符号字进行排序的第一个代码 (int32_t):

我尝试将其更改为对uint16_t 无符号半字进行排序。我几乎完成了代码,但缺少一些东西。问题是排序,架构是ARM(在ARM模式下,不是Thumb);这是我到目前为止所做的:

sort:   STMFD   SP!,{R4-R6,LR}
        MOV     R2,#1   //for (unsigned i = 1;
L1:     CMP     R2,R1
        BHS     L4      //                     i < toSort.size();
        MOV     R3,R2   //      for (unsigned j = i
L2:     SUBS    R3,R3,#1//                          - 1;          --j)
        BLO     L3      //                               j != -1;
        ADD     R6,R0,R3,LSL #2
        LDRH    R4,[R6]
        LDRH    R5,[R6,#2]
        CMP     R5,R4   //              if (toSort[j+1] < toSort[j])
        STRHT   R4,[R6,#2]
        STRHT   R5,[R6] //                      swap(toSort[j], toSort[j+1]);
        BLT     L2     
L3:     ADD     R2,R2,#1//              else break;               ++i)
     B       L1      
L4:     LDMFD   SP!,{R4-R6,PC}
void insertionSort(vector<int>& toSort) 
{                                       
        for (int i = 1; i < toSort.size(); ++i)
                for (int j = i - 1; j >= 0; --j)
                        if (toSort[j+1] < toSort[j])
                                swap(toSort[j], toSort[j+1]);
                        else
                                break; 
} */ This is the code that should be in assembly

【问题讨论】:

  • 请勿发布代码图片。相反,edit 您的问题并将您的代码添加为文本。另外,我不知道您为什么从代码中删除了 cmets,但是对于回答您的问题以有未注释的代码绝对没有帮助。
  • 酷!这样看起来好多了。你能描述一下缺少什么吗?也许以一些示例输入为例,您期望的输出以及您得到的输出。尽量让它简单。
  • @hedgehoga 您可以通过将条件后缀附加到助记符来使任何指令成为条件指令。例如,将STRHLT 写入store half word if less t 汉。
  • 这些链接都没有回答我关于您的问题标题想要表达的问题。对于在他们正在研究的某项搜索结果列表中看到此标题的未来读者来说,这是非常难以理解的。
  • @hedgehoga 如果你有一个旧的汇编程序,menmonic 也可以是STRLTH。请检查一下。

标签: sorting assembly arm


【解决方案1】:

在原始的基础上,您的更改看起来很合理,只是您需要在ADD R6,R0,R3,LSL #2 中移动#1 而不是#2。这是因为#2 用于 4 字节整数,#1 将用于 2 字节整数。这是一个移位量,移位计数反映了您想要缩放索引的 2 的幂。对于 4 字节整数,我们希望乘以/缩放 4,即 22,而对于 2 字节整数,我们希望乘以/缩放 2,即 21 .二进制移位时,要移位的位数乘以 2 的幂。

但是,我很难相信原来的插入排序确实有效。 (您是否独立于您的修改对其进行了测试?)

特别是,正如我所说,“交换发生在条件测试之前”,并且您的指令进一步告诉您 strh 应该是有条件的,这是描述同一问题的另一种方式。

因此,该代码未遵循注释中描述的插入排序。

内部循环中的 if 语句的目的是检测何时到达插入点,并立即停止内部循环。否则如果没有到达插入点,则交换元素并继续内部循环。

该代码改为执行以下操作:

swap ( toSort[j], toSort[j+1 );
if ( toSort[j+1] >= toSort[j] )
    break;

在内循环的末尾。

或者更具体地说:

conditionCodes = toSort[j+1] < toSort[j];
swap ( toSort[j], toSort[j+1 );
if ( conditionCodes is less than )
    continue;
break;

这样做的效果是,当到达适当的停止点时,它会停止,但也会不必要地交换两个元素。

您可以通过更改控制流以使这些存储指令不被执行,或者正如@fuz 所说,在 ARM 上,您可以使这些存储指令本身成为有条件的,从而在最后一次迭代中阻止该交换发生,这考虑到CMPBLT 相距多远,这可能是原作者的意图。但是,这些商店的条件操作在途中丢失了。

【讨论】:

  • 原来的排序是使用strlt,一个有条件的词库。所以这使得交换是有条件的,使用与仍然存在的blt 相同的条件。但是,第一次不交换时退出内部循环对于冒泡排序来说似乎是错误的,这是比较对,而不是进行插入排序。 (或者它只是从排序区域的顶部开始,在这种情况下冒泡是一种有效但效率低下的方式?)这就是你所说的原始排序可能不起作用的意思吗?嗯,貌似16位的版本也忘记改索引了,应该是LSL #1而不是#2。
  • @PeterCordes,我虽然看了原版有strht,但我想我弄错了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-08
相关资源
最近更新 更多