section .data
msg db 10 "Enter string"
msg_len equ $-msg
smsg db 10 "Length is: "
smsg_len equ $-smsg
section .bss
char_ans resb 2
string resb 50
string_len equ $-string
count resb 1
;----------------------------------
%macro print 2
mov rax, 1
mov rdi, 1
mov rsi, %1
mov rdx, %2
syscall
%endmacro
%macro read 2
mov rax, 0
mov rdi, 0
mov rsi, %1
mov rdx, %2
syscall
%endmacro
%macro exit 0
mov rax, 60
mov rsi, 0
syscall
%endmacro
;----------------------------------
section .text
global _start
_start:
print msg, msg_len
read string, string_len
mov [count], rax
print smsg, smsg_len
mov rax, [count]
call display
exit
display:
mov rbx, 16
mov rcx, 2
mov rsi, char_ans+1
cnt:
mov rdx, 0
div rbx
cmp dl, 09h
jbe add30
add dl,37h
add30:
add dl, 30h
mov [rsi], dl
dec rsi
dec rcx
jnz cnt
print char_ans, 2
ret
我觉得应该是
section .text
global _start
_start:
print msg, msg_len
read string, string_len
mov rax, rdx ;VALUE OF RDX MOVED TO RAX SINCE string_leN STORED IN rdx
mov [count], rax
print smsg, smsg_len
mov rax, [count]
call display
exit
1条答案
按热度按时间s3fp2yjn1#
为什么使用RAX
如果一个程序显示“输入字符串”,后面跟着“长度是:”,那么提到的长度应该与实际输入的字符串的字符数有关。所以,输入所进入的缓冲区的长度不是很重要,因为这是一个微不足道的信息,即使在程序启动之前,你也知道。
当使用
SYSREAD
函数时(通过宏或不通过宏),是您提供RDX寄存器中的缓冲区长度,并在返回时,是系统函数为您提供RAX寄存器中输入字符串的(正)长度(如果一切顺利,否则您将在RAX中收到一些负值)。进一步审核
SYSEXIT
的返回码属于RDI寄存器。打字错误?如果您只为 count 变量保留一个字节,那么您不应该在该变量中存储完整的qword。这是一个程序中灾难的配方。
您的 display 代码在显示长度10及以上时会出现问题。十六进制数A到F所需的额外增量为7。您错误地添加了37h,当且仅当您跳过
add dl, 30h
指令时才是正确的,这是任何人都不应该做的事情。这是您可以编写此转换的多种方法之一。重要的是要注意,对于十六进制转换,您可以通过向右移动4次来替换除以16。除法运算是一种代价很高的操作,尤其是您正在使用的128位除法运算。