所以我有大部分代码都可以工作,但是我无法弄清楚如何处理输入句子长度未知的事实。我是装配新手,这有点令人困惑。
(现在我已将它设置为好像长度已知为三个字符,但显然我需要更改它。)
.data
input_msg: .ascii "Enter a random sentence: "
input_msg_len: .long 25
input_str: .ascii "???" # 3rd should get newline
count: .long 0
newline: .long 10
.text
.global _start
_start:
# prompt for input
mov $4, %eax # prompt for input
mov $1, %ebx
mov $input_msg, %ecx
mov input_msg_len, %edx
int $0x80
# get input
mov $3, %eax # 3 to request "read"
mov $0, %ebx # 0 is "console" (keyboard)
mov $input_str, %ecx # input buffer addr
mov $3, %edx # number of symbols typed in
int $0x80 # Go do the service!
again1:
mov $input_str, %ecx
add count, %ecx # count is offset from input_str beginning
mov $4, %eax # to write
mov $1, %ebx # to console display
mov $1, %edx # 1 byte to write
int $0x80 # Do it!
push %ecx # push onto stack
incl count # increment count
cmp $3, count # compare lengths
jnz again1 # jmp again if not 0 (no difference)
mov $0, %edi # use edi as loop counter
mov $4, %eax # print out msg
mov $1, %ebx # etc.
mov $1, %edx # length
int $0x80 # OS, serve!
again2:
pop %ecx
mov $4, %eax # print out msg
mov $1, %ebx # etc.
mov $1, %edx # length
int $0x80 # OS, serve!
inc %edi # increment edi
cmp count, %edi # compare lengths
jnz again2 # jmp again if not 0 (no difference)
# print newline
mov $4, %eax # print out msg
mov $1, %ebx # etc.
mov $newline, %ecx # addr
mov $1, %edx # length
int $0x80 # OS, serve!
# exit
mov $1, %eax # exit
int $0x80 # OS, serve!
基本上,我想知道的是如何让代码适用于任何句子,而不仅仅是3个字符?
答案 0 :(得分:1)
你只需要为input_str
分配一个更长的缓冲区,并读取有效读入的文本量,在read syscall之后的eax中找到。
换句话说,您需要决定接受的最大长度,并将代码更改为以下内容:
注意:可以分配这样的短字符串,静态,当然如果你需要一个大缓冲区(比如从文件中获取数据),你可以改为分配缓冲区动态< / em>的)。同样,对于键盘输入132可能是足够的。
...
input_str: db 132 dup(?) # 132 bytes buffer for input string
input_str_len: .long # length of the string effectively read from user
...
# get input
mov $3, %eax # 3 to request "read"
mov $0, %ebx # 0 is "console" (keyboard)
mov $input_str, %ecx # input buffer addr
mov $131, %edx # _Max_ number of bytes accepted in input_str
int $0x80 # Go do the service!
move %eax, $input_str_len # save nb of bytes effectively read
...
#you can then use input_str_len to control when to exit processing loop etc.
答案 1 :(得分:0)
嗯......你可以做一个%ebx
= 0的sys_brk。这是你原来的“休息” - 保存它。将4k的倍数添加到该值并再次添加sys_brk。将sys_read放入该缓冲区。如果你读完整个4k(在sys_read之后的%eax
中),再向你当前的“break”和sys_brk添加一些,然后再读一些......直到完成。这个“应该”在一个连续的缓冲区中为你提供一切......
更容易决定一些“最大”并且不要让他们输入更多!您可能想要“刷新缓冲区”。如您所知,sys_read(来自键盘)在看到换行符(0xA)之前不会返回。如果讨厌的用户键入了超过%edx
个字符,则其余用户将保留在操作系统的缓冲区中。您可以在3字节缓冲区代码中看到这一点。输入“abcls”。我想你会发现退出后你的shell提示符会读取“ls”,并给你一个目录列表。没问题,但它可能是“rm”或有害的东西!当您的sys_read返回时,如果%eax
小于%edx
,您就完成了。如果%eax
= %edx
(它不会更多),如果缓冲区中的最后一个字符是LF(0xA),那么就完成了。如果没有,则sys_read进入虚拟缓冲区,直到获得该LF。这会使你的代码复杂化,但它“更安全”......
我可以在Nasm语法中尝试一个例子,但我认为我不会更好地尝试AT&amp; T ......:)