X86 NASM程序集将低级字符串转换为大写字母和大写字母

use*_*074 1 x86 assembly nasm

因为我对汇编很新,所以如果用户在汇编中输入大写字母或反之亦然,我有一些关于如何从小写转换为大写的问题.这是我到目前为止:

section .data
Enter db "Enter: "
Enter_Len equ $-Enter

Output db "Output: "
Output_Len equ $-Output

Thanks db "Thanks!"
Thanks_Len equ $-Thanks

Loop_Iter dd 0 ; Loop counter

section .bss
In_Buffer resb 2
In_Buffer_Len equ $-In_Buffer

section .text
global _start

_start:
    ; Print Enter message
    mov eax, 4 ; sys_write
    mov ebx, 1
    mov ecx, Enter
    mov edx, Enter_Len
    int 80h

    ; Read input
    mov eax, 3 ; sys_read
    mov ebx, 0
    mov ecx, In_Buffer
    mov edx, In_Buffer_Len
    int 80h
Run Code Online (Sandbox Code Playgroud)

所以基本上,如果我是正确的,我的edx包含输入的字符串.现在出现了从低级到高级,从大写到小写的困境.因为我对此非常陌生,所以根本不知道该怎么做.任何帮助将非常感激 :)

Ale*_*lke 5

如果您只支持ASCII,则可以使用强制小写 OR 0x20

  or   eax, 0x20
Run Code Online (Sandbox Code Playgroud)

同样,您可以通过清除该位将字母转换为大写:

  and  eax, 0xBF   ; or use ~0x20
Run Code Online (Sandbox Code Playgroud)

正如nneonneo所提到的,可以使用XOR指令交换字符大小写:

  xor  eax, 0x20
Run Code Online (Sandbox Code Playgroud)

只有eax在'a'和'z'或'A'和'Z'之间才有效,所以你必须比较并确保你在范围内:

  cmp  eax, 'a'
  jl   .not-lower
  cmp  eax, 'z'
  jg   .not-lower
  or   eax, 0x20
.not-lower:
Run Code Online (Sandbox Code Playgroud)

我使用了nasm语法.您可能想要确保jl并且jg也是正确的......

如果你需要转换任何国际字符,那么除非你可以调用接受Unicode字符的libc tolower()或toupper()函数,否则这样做会复杂得多.


作为一个公平的问题:它为什么会起作用?(kuhaku问)

ASCII字符(也是ISO-8859-1)在0x41和0x5A之间定义了基本的大写字符,在0x61和0x7A之间定义了小写字符.

要强制4进6和5进7,强制设置第5位(0x20).

要转到大写,则执行相反的操作,删除第5位,使其变为零.

  • @kuhaku 好吧……我说“第 5 位”。你通常从零开始计算位......它总是有点灰色区域,我知道......所以“第5位”是第6位。8-) https://en.wikipedia.org/wiki/Bit_Test (2认同)