Here my code is. Firstly, I call pipe and initialize file descriptors. And their numbers are 3 and 4. Secondly, I call dup2 and redirect STDOUT to file descriptor 4, closing both endings of the pipe aka fds[0] and fds1. In the end, I call execve and the program gives output to the console. But there must be no output at all because the program closes file descriptor 1 aka STDOUT and writes everything to file descriptor 4. Unfortunately, this does not happen at all. The second code block is the code with similar functionality but written in C. So what am doing wrong?
.global main
main:
# pipe(fds)
xor %rax, %rax
mov $22, %al
lea fds(%rip), %rdi
syscall
xor %rax, %rax # fork
mov $57, %al
syscall
cmp $0, %rax
je child_ls
mov $0, %rdi
call wait
finish:
mov $60, %rax
mov $0, %rdi
syscall
child_ls:
# dup2(fds[1], STDOUT_FILEINO)
xor %rax, %rax
mov $33, %al
xor %rdi, %rdi
lea fds(%rip), %rdi
mov 4(%rdi), %ebx
mov %rbx, %rdi
xor %rsi, %rsi
inc %rsi
syscall
# close(fds[0])
xor %rax, %rax
mov $3, %al
lea fds(%rip), %rdi
mov (%rdi), %ebx
mov %rbx, %rdi
syscall
# close(fds[1])
xor %rax, %rax
mov $3, %al
lea fds(%rip), %rdi
mov 4(%rdi), %ebx
mov %rbx, %rdi
syscall
xor %rdx, %rdx
push %rdx
lea arg_ls(%rip), %rdi
push %rdi
lea cmd_ls(%rip), %rdi
push %rdi
mov %rsp, %rsi
call execve
cmd_ls:
.string "/bin/ls"
arg_ls:
.string "-l"
fds:
.int 0, 0
Here the result of assembly code is.
The code with similar functionality but written in C. In C everything works fine and there is no output to the console.
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main()
{
char *command[3] = {"/bin/ls", "-l", 0};
int fd[2];
pipe(fd);
pid_t pid = fork();
if (pid == 0)
{
dup2(fd[1], 1);
execvp(command[0], command);
}
wait(0);
return 0;
}