Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 将字符串转换为大写_String_Assembly_X86 64_Att - Fatal编程技术网

String 将字符串转换为大写

String 将字符串转换为大写,string,assembly,x86-64,att,String,Assembly,X86 64,Att,我试图在汇编中迭代一个字符串,将小写字母改为大写,并在字符串为0时停止,但似乎出现了一些错误(我似乎缺少一个概念)。我搞不清楚问题是什么或发生了什么 以下是我到目前为止的情况: Upper: movq (%rbx), %rcx movq $0, %rdi call check call fin add %rdi, %rax ret fin: c

我试图在汇编中迭代一个字符串,将小写字母改为大写,并在字符串为0时停止,但似乎出现了一些错误(我似乎缺少一个概念)。我搞不清楚问题是什么或发生了什么

以下是我到目前为止的情况:

Upper:
        movq    (%rbx), %rcx
        movq    $0, %rdi
        call    check
        call    fin
        add     %rdi, %rax
        ret

    fin:
        cmpb    $0x0, %r9b
        jne     check
        ret

    check:
        movb    (%rcx, %rdi), %r9b
        cmp     $'Z', %r9b
        jg      toUpper
        jmp     next

    toUpper:
        sub     %r9b, 0x20
        jmp     next

    next:
        incq    %rdi
        jmp     fin

看起来,您的代码有点复杂,很难理解您要实现的算法

处理此类问题时,通常先用C或伪代码写下基本算法:

  • 对于每个字符
    c
    • 如果
      c
      为空字节:完成
    • 如果
      c
      低于
      'a'
      :忽略
    • 如果
      c
      高于
      'z'
      :忽略
    • 其他:将
      'A'
      'A'
      的差异添加到
      c
这几乎直接转化为以下装配程序:

upper:

    ; Read next character
    mov (%rdi), %al

    ; Test for zero byte
    test %al, %al
    je done

    ; Test for <'a' and >'z'
    cmp $'a', %al
    jl next
    cmp $'z', %al
    jg next

    ; We have a lower case character, so convert to upper case
    sub $0x20, %al ; Difference between 'A' and 'a'
    mov %al, (%rdi)

next:

    ; Increment pointer
    inc %rdi
    jmp upper

done:
    ret
输出

Upper case: ABC 123 <=>? 987 XYZ!
大写:ABC 123?987 XYZ!

您能演示一下如何调用
Upper
?它似乎没有遵循常见的调用约定。添加0xe0是编写
-0x20
的一种不同寻常的方式。通常情况下,您将
sub$0x20,%al
或仅使用
和$~0x20,%al
屏蔽小写位。这两者都更直观。另外,通过将load/test/jnz放在底部,可以避免在循环中使用无条件的
jmp
。(跳转到循环入口,或剥离第一次迭代的部分)。谢谢你指出这一点,我已经修复了添加。我只是计算了差异,并没有注意到这个数字是负数:DRegarding循环结构:我同意你的观点,但在这种情况下,尽量靠近伪代码是经过深思熟虑的。在实践中,做……而方法显然是这里的方法(或者只是用C编写程序和使用编译器……),是的,尽管我考虑了{},但是循环是ASM中循环的正常/惯用方式。但有足够的条件逻辑,添加循环条目分支可能会使代码不明显的人更难理解。顺便说一句,有一些更多的信息,包括如何使用sub/cmp/ja而不是2x cmp/jcc进行范围检查。