汇编程序,用于将输入字符串变为小写
A program in assembly to make an input string to lowercase
我正在尝试用 Assembly x86-64 为英特尔 64 位处理器编写程序。该程序应使用 gas(GNU 汇编器)和 运行 on Linux 编译。问题是编写一个名为 lowercase 的程序,它接受一个输入字符串并打印该字符串的小写字母。
应该这样编译:
$> echo "STRING" | ./lowercase
string
$>
我写了这个程序,但问题是它无限打印空格。谁能帮我理解为什么下面的代码会这样?
.section .bss
.comm buf, 1
.section .text
.globl _start
_start:
mov , %bh
mov , %ch
mov [=11=], %dh
Loop:
mov [=11=], %rax # syscall number for read
mov [=11=], %rdi # where to read from: stdin
mov $buf, %rsi # buffer adr
mov , %rdx # length of the buffer in bytes
syscall
cmpb %dh, buf # if read returns 0 (EOF) or less then 0 exit
jle Exit
cmpb %bh, buf # if the character is less than 65 (Char A) print it
jl Write
cmpb %ch, buf # if the charcter is less than 97 make it lowercase
jl ToLowercase
Write:
mov , %rax # system call for write
mov , %rdi # file handle for stdout
mov $buf, %rsi # address of string to output
mov , %rdx # number of bytes
syscall
jmp Loop
ToLowercase:
addb , buf # Make the character lowercase
jmp Write # And go back to output it
Exit:
mov , %rax # system call for exit
movb [=11=], %dil # return code
syscall
这一行:
cmpb %dh, buf # if read returns 0 (EOF) or less then 0 exit
您使用系统调用的计数参数修改了 %rdx(因此修改了 %dh)。此外,syscall 没有保留 %rdx 的合同,因此此检查无效。
此外,来自系统调用(linux、其他)的 return 值在 %rax 中,因此您正在使用 buf 检查未定义的值 (%dh)?更像是
cmp , %rax
jlt Exit
将从读取中测试 return。然后你需要看看你是不是在'A'..'Z':
...
mov buf, %dl
cmp $'A', %dl
jl write
cmp $'Z', %dl
jle ToLowerCase
...
我正在尝试用 Assembly x86-64 为英特尔 64 位处理器编写程序。该程序应使用 gas(GNU 汇编器)和 运行 on Linux 编译。问题是编写一个名为 lowercase 的程序,它接受一个输入字符串并打印该字符串的小写字母。 应该这样编译:
$> echo "STRING" | ./lowercase
string
$>
我写了这个程序,但问题是它无限打印空格。谁能帮我理解为什么下面的代码会这样?
.section .bss
.comm buf, 1
.section .text
.globl _start
_start:
mov , %bh
mov , %ch
mov [=11=], %dh
Loop:
mov [=11=], %rax # syscall number for read
mov [=11=], %rdi # where to read from: stdin
mov $buf, %rsi # buffer adr
mov , %rdx # length of the buffer in bytes
syscall
cmpb %dh, buf # if read returns 0 (EOF) or less then 0 exit
jle Exit
cmpb %bh, buf # if the character is less than 65 (Char A) print it
jl Write
cmpb %ch, buf # if the charcter is less than 97 make it lowercase
jl ToLowercase
Write:
mov , %rax # system call for write
mov , %rdi # file handle for stdout
mov $buf, %rsi # address of string to output
mov , %rdx # number of bytes
syscall
jmp Loop
ToLowercase:
addb , buf # Make the character lowercase
jmp Write # And go back to output it
Exit:
mov , %rax # system call for exit
movb [=11=], %dil # return code
syscall
这一行:
cmpb %dh, buf # if read returns 0 (EOF) or less then 0 exit
您使用系统调用的计数参数修改了 %rdx(因此修改了 %dh)。此外,syscall 没有保留 %rdx 的合同,因此此检查无效。
此外,来自系统调用(linux、其他)的 return 值在 %rax 中,因此您正在使用 buf 检查未定义的值 (%dh)?更像是
cmp , %rax
jlt Exit
将从读取中测试 return。然后你需要看看你是不是在'A'..'Z':
...
mov buf, %dl
cmp $'A', %dl
jl write
cmp $'Z', %dl
jle ToLowerCase
...