我正在制作一个程序,只需简单地接受用户输入两次,然后将结果打印到标准输出中。我遇到的问题是,当从输入中断(在 eax 中)返回结果时,我将它推入堆栈以供以后使用。我再次为第二个用户输入执行此操作。
我到目前为止的代码是:
%include "system.inc" ; used for renaming of interrupts (sys.write and sys.read)
section .data
greet: db 'Hello!', 0Ah, 'What is your name?', 0Ah
greetL: equ $-greet ;length of string
colorQ: db 'What is your favorite color?', 0Ah
colorL: equ $-colorQ
suprise1: db 'No way '
suprise1L: equ 7
comma: db ', '
commaL: equ $-comma
suprise3: db ' is my favorite color, too!', 0Ah
suprise3L: equ $-suprise3
section .bss
name: resb 50
color: resb 50
section .text
global _start
_start:
greeting:
mov eax, 4
mov ebx, 1
mov ecx, greet
mov edx, greetL
sys.write
getname:
mov eax, 3
mov ebx, 0
mov ecx, name
mov edx, 50
sys.read
xor ecx, ecx
mov eax, ecx
push ecx
askcolor:
mov eax, 4
mov ebx, 1
mov ecx, colorQ
mov edx, colorL
sys.write
getcolor:
mov eax, 3
mov ebx, 0
mov ecx, color
mov edx, 50
sys.read
xor ebx, ebx
mov ebx, eax
push ebx
thesuprise:
mov eax, 4
mov ebx, 1
mov ecx, suprise1
mov edx, suprise1L
sys.write
xor ebx, ebx
xor ecx, ecx
xor edx, edx
pop ecx
sub ecx, 1
mov edx, ecx
mov eax, 4
mov ebx, 1
mov ecx, name
mov edx, edx
sys.write
mov eax, 4
mov ebx, 1
mov ecx, comma
mov edx, commaL
sys.write
xor ebx, ebx
xor ecx, ecx
xor edx, edx
pop ebx
sub ebx, 1
mov edx, ebx
mov eax, 4
mov ebx, 1
mov ecx, color
mov edx, edx
sys.write
mov eax, 4
mov ebx, 1
mov ecx, suprise3
mov edx, suprise3L
sys.write
done:
mov eax, 1
mov ebx, 0
sys.exit
我在输出中出现严重的间距问题,很可能是因为当我按下/弹出它时我如何处理 eax 中返回的值。有没有办法解决这个问题/我做错了吗?
答案 0 :(得分:1)
greeting:
mov eax, 4
mov ebx, 1
mov ecx, greet
mov edx, greetL
sys.write
getname:
mov eax, 3
mov ebx, 0
mov ecx, name
mov edx, 50
sys.read
我不知道这些sys.write
和sys.read
宏应该为您做什么,但是在调用系统调用之前,他们可能会使用正确的值加载eax
int 0x80
,所以你可能不需要自己做。否则他们没有多大意义......
(但这不是问题; 4
和3
分别是32位Linux x86上write
和read
的正确系统调用号。)
实际问题可能在这里:
xor ecx, ecx
mov eax, ecx
push ecx
这看起来是错误的:您将自己与ecx
进行异或运算,将其设置为零。然后,您将ecx
(现在为0)分配给eax
(这是系统调用的结果),因此系统调用的结果将被丢弃。然后你将ecx
(仍为0)推到堆栈上。
更进一步,你有:
xor ebx, ebx
xor ecx, ecx
xor edx, edx
pop ecx
sub ecx, 1
mov edx, ecx
...这也很奇怪:当你要从其他地方重新加载它们时,为什么归零ecx
和edx
以及xor
指令?
我猜你可能只有mov
的操作数错误。而不是:
xor ecx, ecx
mov eax, ecx
push ecx
......如果你说:
xor ecx, ecx
mov ecx, eax
push ecx
....你至少会成功地将eax
中的值(来自系统调用的返回代码)推送到堆栈上,尽管说起来会简单得多:
push eax
最后:你问“名字”问题,并且(假设上面已修复)将结果长度推到堆栈上。然后你问“颜色”问题,并将结果长度推到堆栈上。
然后你打印“名字”惊喜,使用从堆栈中弹出的第一个值,这是你从“颜色”问题中保存的长度。 (堆叠是先进先出!)然后使用“名称”问题的长度打印“颜色”惊喜。
答案 1 :(得分:0)
感谢Matt和ott。
以下是解决方案:
%include "system.inc"
section .data
greet: db 'Hello!', 0Ah, 'What is your name?', 0Ah
greetL: equ $-greet ;length of string
colorQ: db 'What is your favorite color?', 0Ah
colorL: equ $-colorQ
suprise1: db 'No way '
suprise1L: equ 7
comma: db ', '
commaL: equ $-comma
suprise3: db ' is my favorite color, too!', 0Ah
suprise3L: equ $-suprise3
section .bss
name: resb 50
color: resb 50
section .text
global _start
_start:
greeting:
mov eax, 4
mov ebx, 1
mov ecx, greet
mov edx, greetL
sys.write
getname:
mov eax, 3
mov ebx, 0
mov ecx, name
mov edx, 50
sys.read
sub eax, 1
push eax
askcolor:
mov eax, 4
mov ebx, 1
mov ecx, colorQ
mov edx, colorL
sys.write
getcolor:
mov eax, 3
mov ebx, 0
mov ecx, color
mov edx, 50
sys.read
sub eax, 1
push eax
thesuprise:
mov eax, 4
mov ebx, 1
mov ecx, suprise1
mov edx, suprise1L
sys.write
xor eax, eax
pop eax
mov ecx, eax
pop eax
mov edx, eax
push ecx
mov eax, 4
mov ebx, 1
mov ecx, name
;mov edx, edx
sys.write
mov eax, 4
mov ebx, 1
mov ecx, comma
mov edx, commaL
sys.write
xor eax, eax
pop eax
mov edx, eax
mov eax, 4
mov ebx, 1
mov ecx, color
;mov edx, edx
sys.write
mov eax, 4
mov ebx, 1
mov ecx, suprise3
mov edx, suprise3L
sys.write
done:
mov eax, 1
mov ebx, 0
sys.exit