它需要允许两位数的输入数字,用于指示打印名称的次数。我无法弄清楚如何分离第二个数字,并检查它以确保它在0x30和0x39之间。我还在其中包含0017的名称之后继续得到这个奇怪的盒子。
.data
input_msg_len: .long 26
input_msg: .ascii "Enter a two-digit number: "
name: .ascii "Michael Chabon\n"
name_len: .long 16
max: .long 0
count: .long 0
tmp: .long 0
input_str: .ascii "??"
.text
.global _start
_start:
mov $4, %eax
mov $1, %ebx
mov $input_msg, %ecx
mov input_msg_len, %edx
int $0x80
mov $3, %eax
mov $0, %ebx
mov $input_str, %ecx
mov $2, %edx
int $0x80
mov $input_str, %eax
add count, %eax
mov $input_str, %eax
mov (%eax), %bl
cmp $0x30, %bl
jl _start
cmp $0x39, %bl
jg _start
mov count, %eax
inc %eax
mov %eax, count
sub $0x30, %bl
mov %bl, max
mov $10, %bl
imul %bl
mov %bl, max
#Not sure how to check second char in input_str.
#Want to check it then subtract $0x30 and move to tmp before adding tmp to max.
mov $0, %edi
again:
cmp max, %edi
je end
mov $4, %eax
mov $1, %ebx
mov $name, %ecx
mov name_len, %edx
int $0x80
inc %edi
jmp again
end:
mov $1, %eax
int $0x80
提前致谢!
答案 0 :(得分:0)
您的代码中存在一些错误。
下面,该块的2个第一行是多余的,因为mov $input_str, %eax
无论如何都会覆盖eax
。
mov $input_str, %eax
add count, %eax
mov $input_str, %eax
然后在这里,将count
加载到eax
这里是没有意义的:
mov count, %eax
inc %eax
mov %eax, count
你可以用更短更清晰的方式做到这一点:
incl count
然后,下一个错误是您最近将count
加载到eax
,然后将加载到count
的{{1}}的最低8位乘以10,代码:
al
所以,根据我的直觉,你不想 mov (%eax), %bl // bl = first character
cmp $0x30, %bl
jl _start
cmp $0x39, %bl
jg _start
mov count, %eax // eax = count
inc %eax // eax++
mov %eax, count // count = eax
sub $0x30, %bl // 0 <= bl <= 9
mov %bl, max // max = bl <- you lose this value in the next mov %bl, max
mov $10, %bl // bl = 10
imul %bl // ax = 10 * and(count, 0xff) // ax = al*bl (signed multiply)
mov %bl, max // max = 10 <- here you overwrite the value of max with 10
,而是ax = 10 * and(count, 0xff)
。 10 * (first number)
在imul %bl
和al
之间进行了对齐,并将结果存储在bl
中。所以上面的代码可以改成这样的代码:
ax
然后,您可以与第一个字符类似地检查第二个字符:
mov (%eax), %bl // bl = first character
cmp $0x30, %bl
jl _start
cmp $0x39, %bl
jg _start
incl count
pushl %eax // push eax to stack
sub $0x30, %bl // 0 <= bl <= 9
mov $10, %al // al = 10
imul %bl // ax = 10 * bl (signed multiply)
mov %al, max // 0 <= max <= 90
我强烈建议您学习使用一些调试器。 gdb有几个前端,我认为根据我的经验,ddd效果最好。 gdbtui也很方便。