• 汇编练习Fix string case


    In this Kata, you will be given a string that may have mixed uppercase and lowercase letters and your task is to convert that string to either lowercase only or uppercase only based on:

    • make as few changes as possible.
    • if the string contains equal number of uppercase and lowercase letters, convert the string to lowercase.

    For example:

    solve("coDe") = "code". Lowercase characters > uppercase. Change only the "D" to lowercase.
    solve("CODe") = "CODE". Uppercase characters > lowecase. Change only the "e" to uppercase.
    solve("coDE") = "code". Upper == lowercase. Change all to lowercase.

    More examples in test cases. Good luck!

    Please also try:

    自己的垃圾超时代码!!bug一堆

    SECTION .text
    global solve
    extern malloc
    extern strlen
    ; Returns pointer to new string, the value of which is defined by the description
    ; NOTE: Please allocate the memory for the new string using C's malloc
    ; arg0         = (const char*) original string
    ; return value = (char*)       new string
    solve:
      xor rax,rax
      call strlen
      mov rcx,rax
      mov rsi,rdi
      mov rdx,0
      mov rbx,0
      .loop:
      cmp rcx,0
      jle .state2
      cmp byte[rdi],'Z'
      inc rdi
      jle state1
      inc rbx
      jmp .loop
      .state1:
      inc rdx
      jmp .loop
      
      .state2:
      mov rcx,rax
      mov rdi,rsi
      cmp rbx,rdx
      jle .state3
      
      .loop2:
      cmp rcx,0
      jle .state4
      and byte[rdi],32
      dec rcx
      inc rdi
      jmp .loop2
      
      .state3:
      .loop3:
      cmp rcx,0
      jle .state4
      xor byte[rdi],32
      dec rcx
      inc rdi
      jmp .loop3
      
      .state4:
      mov rax,rsi
      ret

    别人大神代码

    https://www.codewars.com/kata/5b180e9fedaa564a7000009a/solutions

    SECTION .text
    global solve
    extern malloc, strlen, strcpy
    
    ; Returns pointer to new string, the value of which is defined by the description
    ; NOTE: Please allocate the memory for the new string using C's malloc
    ; arg0         = (const char*) original string
    ; return value = (char*)       new string
    solve:
      push rdi
      call strlen
      pop rdi
      inc rax
      push rdi
      mov rdi, rax
      call malloc
      pop rdi
      mov rsi, rdi
      mov rdi, rax
      push rax
      call strcpy
      pop rax
      xor rdi, rdi
      push rax
    .loop1:
      cmp byte [rax], 0
      je .loop1_end
      cmp byte [rax], 'A'
      jl .loop1_update
      cmp byte [rax], 'Z'
      jg .check_lowercase
      inc rdi
      jmp .loop1_update
    .check_lowercase:
      cmp byte [rax], 'a'
      jl .loop1_update
      cmp byte [rax], 'z'
      jg .loop1_update
      dec rdi
    .loop1_update:
      inc rax
      jmp .loop1
    .loop1_end:
      pop rax
      push rax
      cmp rdi, 0
      jle .tolower_loop
    .toupper_loop:
      cmp byte [rax], 0
      je .end
      cmp byte [rax], 'a'
      jl .toupper_loop_update
      cmp byte [rax], 'z'
      jg .toupper_loop_update
      sub byte [rax], 32
    .toupper_loop_update:
      inc rax
      jmp .toupper_loop
    .tolower_loop:
      cmp byte [rax], 0
      je .end
      cmp byte [rax], 'A'
      jl .tolower_loop_update
      cmp byte [rax], 'Z'
      jg .tolower_loop_update
      add byte [rax], 32
    .tolower_loop_update:
      inc rax
      jmp .tolower_loop
    .end:
      pop rax
      ret

    这个更厉害

    SECTION .text
    global solve
    extern strdup
    solve:
      call strdup
      push rax
      xor  rcx,rcx
      @a:btr dword[rax],5
         sbb rdx,rdx
         lea rcx,[rcx+rdx*2+1]
         inc rax 
         cmp byte[rax],0
      jne @a
      add rcx,rcx
      ja @c
        mov rax,[rsp]
        @b:or  byte[rax],32
           inc rax
           cmp byte[rax],0
        jne @b   
      @c:
      pop  rax
    ret

    第三个

    SECTION .text
    global solve
    extern malloc, strlen, strcpy
    
    ; Returns pointer to new string, the value of which is defined by the description
    ; NOTE: Please allocate the memory for the new string using C's malloc
    ; arg0         = (const char*) original string
    ; return value = (char*)       new string
    solve:
      push rdi
      call strlen
      lea rdi, [rax+1]
      call malloc
      pop rsi         ; this gets original pushed rdi value; now rsi = source string, rdi = dest string  for strcpy 
      mov rdi, rax
      push rax
      call strcpy
      pop rax         ; rax is base of new output string  - this remains unmodified hereafter     
      xor edi, edi    ; this will count number of upper/lower case chars
      xor esi, esi    ; this is offset from rax
      xor edx, edx    ; this is used to detect lower or upper case characters
      
    .loop:
      mov bl, [rax+rsi]
      test bl, bl     ; exit at zero char
      jz .done
      cmp bl, 'a'
      setge cl
      cmp bl, 'z'
      setg dl
      xor dl, cl      ; dl = 1 if bl is a lower case char
      add edi, edx    ; inc count if lower case
      cmp bl, 'A'
      setge cl
      cmp bl, 'Z'
      setg dl
      xor dl, cl      ; dl = 1 if bl is an upper case char
      sub edi, edx    ; dec count if upper case
      inc esi         ; count up through the string
      jmp .loop
      
    .done:
      dec esi         ; point to last character in string
      js .exit
      test edi, edi
      js .toupper     ; convert to upper only if n(upper) > n(lower)
      
    .tolower:
      or byte [rax+rsi], 32     ; make lower case
      dec esi                   ; and count back down through the string
      jns .tolower
      jmp .exit
      
    .toupper:
      and byte [rax+rsi], ~32   ; make upper case
      dec esi                   ; and count back down through the string
      jns .toupper
      
    .exit:
      ret

    这个思路跟我一样

    SECTION .text
    global solve
    extern malloc, strlen, strcpy
    
    ; Returns pointer to new string, the value of which is defined by the description
    ; NOTE: Please allocate the memory for the new string using C's malloc
    ; arg0         = (const char*) original string
    ; return value = (char*)       new string
    solve:
      push rdi
      call strlen
      pop rdi
      inc rax
      push rdi
      mov rdi, rax
      call malloc
      pop rdi
      mov rsi, rdi    ;rsi = source string, rdi = dest string
      mov rdi, rax
      push rax
      call strcpy
      pop rax
      xor rdi, rdi    ;this will count number of upper/lower case chars
      push rax        ;rax is base of output string
      xor rsi, rsi    ;this is offset from rax
      
    .loop:
      mov bl, [rax+rsi]
      test bl, bl
      jz .done
      cmp bl, 'a'
      setge cl
      cmp bl, 'z'
      setg ch
      xor cl, ch
      and rcx, 1
      add rdi, rcx
      cmp bl, 'A'
      setge cl
      cmp bl, 'Z'
      setg ch
      xor cl, ch
      and rcx, 1
      sub rdi, rcx
      inc rsi
      jmp .loop
      
    .done:
      dec rsi
      js .exit
      test rdi, rdi
      js .toupper
    .tolower:
      or byte [rax+rsi], 32     ; make lower case
      dec rsi
      jns .tolower
      jmp .exit
    .toupper:
      and byte [rax+rsi], 95    ; make upper case
      dec rsi
      jns .toupper
    
    .exit:
      pop rax
      ret

    目前不足:无法写出正确的代码,总是有很多bug,对asm还不了解

  • 相关阅读:
    周末现场支持
    变量&字符串
    dead loop、continue & break、while...else语句
    运算符、流程控制、while循环
    二进制、字符编码、浮点数、列表
    字符串操作
    元祖、hash了解、字典、集合
    大数据处理
    含有虚函数的派生类的sizeof
    eclipse UML插件 安装和使用
  • 原文地址:https://www.cnblogs.com/pppyyyzzz/p/13634191.html
Copyright © 2020-2023  润新知