汇编练习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还不了解