Reputation: 6814
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?
Upvotes: 3
Views: 1299
Reputation: 6814
Thanks to Matt and ott.
Here is the solution:
%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
Upvotes: 0
Reputation: 47058
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
I don't know what these sys.write
and sys.read
macros are expected to do for you, but the chances are that they load eax
with the correct value before invoking a syscall with int 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
and 3
are the correct syscall numbers for write
and read
respectively on 32-bit Linux x86.)
The actual problem is probably here:
xor ecx, ecx
mov eax, ecx
push ecx
This looks wrong: you are exclusive-ORing ecx
with itself, which sets it to zero. Then you're assigning ecx
(which is now 0) to eax
(which is the result of the syscall), so the result of the syscall gets thrown away. Then you're pushing ecx
(which is still 0) onto the stack.
Still further on, you have:
xor ebx, ebx
xor ecx, ecx
xor edx, edx
pop ecx
sub ecx, 1
mov edx, ecx
...which is also odd: why zero ecx
and edx
with the xor
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:
xor ecx, ecx
mov eax, ecx
push ecx
...if you said:
xor ecx, ecx
mov ecx, eax
push ecx
....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:
push eax
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.
Upvotes: 1