繁体   English   中英

编写汇编语言代码来反转字符串

[英]Write an assembly language code to reverse a string

这是一个反转字符串的代码我真的很难完成这段代码。 我找不到它有什么问题,但是输出是错误的。

    mov esi, OFFSET source             
    mov edi, OFFSET target          
    add edi, SIZEOF target-2
    mov ecx, SIZEOF source-1   

L1:                             
    mov  al, [esi]              
    mov  [edi], al                
    inc  esi                      
    dec  edi                     
    loop L1                    

向函数传递两个长度有点奇怪。 如果两者不匹配,可能会发生各种不好的事情。 最好明确传递字符串的长度,或者让代码计算出长度。
由于获取 old-skool c-string 的长度对代码来说很重要,但对 google 来说很简单,我将把它作为参数传递。

“……输出错误。”
问题是您的字符串需要以零结尾,但您没有将终止零放在目标字符串上。

首先,如果您想让字符串成为有效的 c 样式字符串,请确保添加终止零,如下所示: source db "test test",0

    mov esi, OFFSET source        ;Start of source
    mov edi, OFFSET target        ;start of dest
    ;length EQU SIZEOF source      ;we are reversing source
    mov ecx, SIZEOF source        ;Length of the string 
                                  ;(includes the terminating 0)

Setup:
    ;//a c-string must have a terminating 0!
    xor eax,eax                   ;al=0, put the terminating zero in first   
L1:                             
    mov  [edi+ecx-1], al          ;if length(ecx)=1, then write to [edi] directly.  
    mov  al, [esi]               
    inc  esi                                           
    loop L1 

代码备注
不需要保持三个计数器在飞行中( ediesiecx ),两个就足够了。 esi倒计时, ecx倒计时。
x86 有很多非常有用的寻址模式,它们大多是免费的性能明智的。
最后一次迭代将读取al的终止零,我们不需要反转它,并且您已经在开始时编写了它,所以它被(悄悄地)删除了。
由于终止为零,长度至少为 1。这很好,因为如果以某种方式将 0 送入loop ,它将“永远”循环; 不好(“永远”是 4+ 十亿次)

请注意,您的代码没有考虑 Unicode,因此它不适用于 UTF8,但我们假设它只是一个学习练习。

如果你遵循ABI ,那么你可以只在寄存器中传递参数,这意味着你可以跳过一些初始化。 鉴于您的代码不会因原始速度而获得任何奖励,因此我跳过了这一步。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM