title: What is the relation between (carry flag) and syscall in assembly (x64 Intel syntax on Mac Os)?
body: <p>I am new to the assembly language, and I have to make an implementation of <a href="https://man7.org/linux/man-pages/man2/read.2.html" rel="nofollow noreferrer">read</a> function using assembly language <code>x64</code> in <code>MAC</code>.
  so far this is what I did :</p>
  <pre><code>;;;;;;ft_read.s;;;;;;
  
  global _ft_read:
  section .text
  extern ___error
  
  _ft_read:
      mov rax, 0x2000003 ; store syscall value of read on rax 
      syscall            ; call read and pass to it rdi , rsi, rdx  ==&gt; rax read(rdi, rsi, rdx)
      cmp rax, 103       ; compare rax with 103 by subtracting 103 from rax ==&gt; rax - 103
      jl _ft_read_error  ; if the result of cmp is less than 0 then jump to _ft_read_error
      ret                ; else return the rax value which is btw the return value of syscall
  
  _ft_read_error:
      push rax
      call ___error
      pop rcx
      mov [rax], rcx
      mov rax, -1
      ret
  </code></pre>
  <p>as you can see above, I call read with syscall, and then I compare the returned value of read syscall that stored in rax with <code>103</code>, I will explain why I compare it with <code>103</code> but before that, let me explain something else, which is <a href="https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/intro.2.html" rel="nofollow noreferrer">errno</a> (man page of mac), this is what is written in the manual page about <code>errno</code>:</p>
  <blockquote>
  <p>When a system call detects an error, it returns an integer value indicat-ing indicating
  ing failure (usually -1) and sets the variable errno accordingly.  &lt;This
  allows interpretation of the failure on receiving a -1 and to take action
  accordingly.&gt; Successful calls never set errno; once set, it remains
  until another error occurs.  It should only be examined after an error.
  Note that a number of system calls overload the meanings of these error
  numbers, and that the meanings must be interpreted according to the type
  and circumstances of the call.</p>
  <p>The following is a complete list of the errors and their names as given
  in &lt;sys/errno.h&gt;.</p>
  <p><code>0</code> Error 0.  Not used.</p>
  <p><code>1</code> EPERM Operation not permitted.  An attempt was made to perform an operation limited to processes with appropriate privileges or to the
  owner of a file or other resources.</p>
  <p><code>2</code> ENOENT No such file or directory.  A component of a specified pathname did not exist, or the pathname was an empty string.</p>
  <p>..................................................I'll skip this part (I wrote this line btw)..................................................</p>
  <p><code>101</code> ETIME STREAM ioctl() timeout.  This error is reserved for future use.</p>
  <p><code>102</code> EOPNOTSUPP Operation not supported on socket.  The attempted operation is not supported for the type of socket referenced; for example, trying to accept a connection on a datagram socket.</p>
  </blockquote>
  <p>and as I understand and after I debugged a lot of time using <code>lldb</code>, I noticed that <code>syscall</code> returns one of those numbers that are shown in the <code>errno</code> man page, for example when I pass a bad file descriptor, in my <code>ft_read</code> function using the below <code>main.c</code> code like this :</p>
  <pre><code>int bad_file_des = -1337;// a file descriptor which it doesn't exist of course, you can change it with -42 as you like
  ft_read(bad_file_des, buff, 300);
  </code></pre>
  <p>our <code>syscall</code> returns <code>9</code> which is stored in <code>rax</code> so I compare if <code>rax</code> &lt; 103 (because errno values are from 0 to 102) then jump to <code>ft_read_error</code> because that's what it should do.</p>
  <p>Well everything works as I planned but there is a problem which came from nowhere, when I open an existing file and I pass it's file descriptor to my <code>ft_read</code> function as shown in the below <code>main.c</code>, our read <code>syscall</code> returns <code>&quot;the number of bytes read is returned&quot;</code>, this is what <code>read</code> syscall returns as described on the manual:</p>
  <blockquote>
  <p>On success, the number of bytes read is returned (zero indicates end
  of file), and the file position is advanced by this number.  It is
  not an error if this number is smaller than the number of bytes
  requested; this may happen for example because fewer bytes are
  actually available right now (maybe because we were close to end-of-
  file, or because we are reading from a pipe, or from a terminal), or
  because read() was interrupted by a signal.  See also NOTES.</p>
  <p>On error, -1 is returned, and errno is set appropriately.  In this
  case, it is left unspecified whether the file position (if any)
  changes.</p>
  </blockquote>
  <p>and in my main that it works pretty fine, I pass to my <code>ft_read</code> function a good file descriptor, a buffer to store the data, and 50 bytes to read, so <code>syscall</code> will return <code>50</code> that stored in <code>rax</code>, then the comparison makes it's job &gt;&gt; <code>rax = 50</code> &lt; 103 then it will jump to <code>ft_read_error</code> even that there is no error, just because <code>50</code> is one of those <code>errno</code> error numbers which is not in this case.</p>
  <p>someone suggests to use <code>jc</code> (jump if carry flag is set) rather than <code>jl</code> (jump if less) as shown in the code below :</p>
  <pre><code>;;;;;;ft_read.s;;;;;;
  
  global _ft_read:
  section .text
  extern ___error
  
  _ft_read:
      mov rax, 0x2000003 ; store syscall value of read on rax 
      syscall            ; call read and pass to it rdi , rsi, rdx  ==&gt; rax read(rdi, rsi, rdx)
                         ; deleted the cmp
      jc _ft_read_error  ; if carry flag is set then jump to _ft_read_error
      ret                ; else return the rax value which is btw the return value of syscall
  
  _ft_read_error:
      push rax
      call ___error
      pop rcx
      mov [rax], rcx
      mov rax, -1
      ret
  </code></pre>
  <p>and guess what, it works perfectly and <code>errno</code> returns <code>0</code> using my <code>ft_read</code> when there is no error, and it returns the appropriate error number when there is an error.</p>
  <p>but the problem is that I don't know why the <code>carry flag</code> got set, when there is no <code>cmp</code>, does syscall set the <code>carry flag</code> when there is an error during the call, or there is another thing happening in the background? I want a detailed explanation about the relation between the syscall and <code>carry flag</code>, I am still new to assembly and I want to learn it so badly, and thanks in advance.</p>
  <p><strong>what is the relation between the <code>syscall</code> and <code>carry flag</code> and how <code>syscall</code> sets it?</strong></p>
  <p>this is my <code>main.c</code> function that I use to compile the assembly code above :</p>
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;fcntl.h&gt;
  #include &lt;errno.h&gt;
  
  ssize_t ft_read(int fildes, void *buf, size_t nbyte);
  
  int     main()
  {
      /*-----------------------------------------------------------------------*/
      ///////////////////////////////////////////////////////////////////////////
      /********************************ft_read**********************************/
      int     fd = open(&quot;./main.c&quot;, O_RDONLY);
      char    *buff = calloc(sizeof(char), 50 + 1);
      int     ret = ft_read(fd, buff, 50);
  
      printf(&quot;ret value = %d,  error value = %d : %s\n&quot;, ret, errno, strerror(errno));
      //don't forget to free ur buffer bro, this is just a test main don't be like me.
      return (0);
  }
  </code></pre>