我正在尝试用汇编语言x86-64为英特尔64位处理器编写一个程序。该程序应使用gas (GNU汇编程序)编译,并在Linux上运行。问题是编写一个名为lowercase的程序,该程序接受输入字符串并打印该字符串的小写。它应该像这样编译:
$> echo "STRING" | ./lowercase
string
$>我写了这个程序,但问题是它会无限地打印空格。谁能帮助我理解为什么下面的代码是这样的?
.section .bss
.comm buf, 1
.section .text
.globl _start
_start:
mov $65, %bh
mov $97, %ch
mov $0, %dh
Loop:
mov $0, %rax # syscall number for read
mov $0, %rdi # where to read from: stdin
mov $buf, %rsi # buffer adr
mov $1, %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 $1, %rax # system call for write
mov $1, %rdi # file handle for stdout
mov $buf, %rsi # address of string to output
mov $1, %rdx # number of bytes
syscall
jmp Loop
ToLowercase:
addb $32, buf # Make the character lowercase
jmp Write # And go back to output it
Exit:
mov $60, %rax # system call for exit
movb $0, %dil # return code
syscall发布于 2021-11-21 14:48:46
这一行:
cmpb %dh, buf # if read returns 0 (EOF) or less then 0 exit您使用syscall的count参数修改了%rdx (因此为%dh)。此外,syscall没有保留%rdx的合同,因此此检查无效。
另外,syscall (linux,其他)的返回值是%rax,所以您使用buf?检查未定义的值(%dh)?更像是
cmp $1, %rax
jlt Exit将测试从read返回的结果。然后你需要看看你是否在‘a’..‘z’中:
...
mov buf, %dl
cmp $'A', %dl
jl write
cmp $'Z', %dl
jle ToLowerCase
...https://stackoverflow.com/questions/70055429
复制相似问题