x86 NASM 程序集 - 堆栈问题
我正在开发一个程序,只需接受用户的输入两次,然后稍后将结果打印到标准输出。我遇到的问题是,当结果从输入中断(在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 中返回的值。有什么办法可以解决这个问题/我做错了吗?
I am working on a program to simply take in a user's input twice, and then print the result out to the standard output at a later time. The problem I am having is that, when the result is returned from the input interrupt (in eax), I push it onto the stack for use later. I do this again for the second user input.
The code I have so far is:
%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
I get severe problems with spacing in the output, most likely because of how I handle the values returned in eax when I push/pop it. Is there any way to fix this/ am I doing this wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不知道这些
sys.write
和sys.read
宏将为您做什么,但它们很可能会加载eax
在使用int 0x80
调用系统调用之前使用正确的值,因此您可能不需要自己执行此操作。否则它们没有多大意义...(但这不是问题;
4
和3
是write
和write
的正确系统调用编号。 code>read 分别在 32 位 Linux x86 上。)实际的问题可能在这里:
这看起来是错误的:您将
ecx
与其自身进行异或运算,这将其设置为零。然后,您将 ecx(现在为 0)分配给 eax(系统调用的结果),因此系统调用的结果被丢弃。然后你将ecx
(仍然是0)压入堆栈。更进一步,你有:
...这也很奇怪:为什么使用
xor
指令将 ecx 和edx 为零,当你只是要从其他地方重新加载它们,然后再执行一些说明吗?
我猜您可能只是将
mov
的操作数搞错了。而不是:...如果您说:
...您至少会成功地将 eax 中的值(系统调用的返回代码)推送到堆栈上,尽管它将是简单地说:
最后:你问“名称”问题,并且(假设上面的问题已修复)将结果长度压入堆栈。然后你问“颜色”问题,并将结果长度压入堆栈。
但是然后你使用从堆栈中弹出的第一个值打印“名称”惊喜,这是你从“颜色”问题中保存的长度。 (堆栈是后进先出的!)然后,您可以使用“名称”问题的长度来打印“颜色”惊喜。
I don't know what these
sys.write
andsys.read
macros are expected to do for you, but the chances are that they loadeax
with the correct value before invoking a syscall withint 0x80
, so you probably don't need to do it yourself. There's not much point in them otherwise...(That's not the problem though;
4
and3
are the correct syscall numbers forwrite
andread
respectively on 32-bit Linux x86.)The actual problem is probably here:
This looks wrong: you are exclusive-ORing
ecx
with itself, which sets it to zero. Then you're assigningecx
(which is now 0) toeax
(which is the result of the syscall), so the result of the syscall gets thrown away. Then you're pushingecx
(which is still 0) onto the stack.Still further on, you have:
...which is also odd: why zero
ecx
andedx
with thexor
instructions, when you're just going to reload them from elsewhere a couple of instructions further on?I guess you may just have the operands of the
mov
the wrong way round. Instead of:...if you said:
....you would at least successfully push the value that was in
eax
(the return code from the syscall) onto the stack, although it would be a lot simpler to just say:Finally: you ask the "name" question, and (assuming the above it fixed) push the resulting length on the stack. Then you ask the "color" question, and push the resulting length on the stack.
But then you print the "name" surprise, using the first value popped from the stack, which is the length you saved from the "color" question. (A stack is last-in-first-out!) Then you use print the "color" surprise using the length from the "name" question.
感谢马特和奥特。
这是解决方案:
Thanks to Matt and ott.
Here is the solution: