0

I am looking through some demos of assembly (using NASM on a Mac, I am new to assembly) and seeing things like this:

; read a byte from stdin
mov eax, 3     ; 3 is recognized by the system as meaning "read"
mov ebx, 0     ; read from standard input
mov ecx, variable    ; address to pass to
mov edx, 1     ; input length (one byte)
int 0x80             ; call the kernel

I am beginning to understand that eax, ebx, etc. are "general registers", which is where you store common things. Still have more to learn there but I get the gist of it.

But I am confused as to where the values like 3 (recognized by the system as meaning "read") and 0 (read from standard input) are coming from. How do you know that 0 means "standard input"? Is there a list of such integer values, or some book or standard reference?

Lance
  • 75,200
  • 93
  • 289
  • 503
  • The secret is in the next instruction: `int 0x80`. That is a call to a system routine, which inspects the values in other registers to see what it should do. – Jongware Dec 21 '14 at 19:32
  • This has nothing to do with assembly really, it's like a contract defined by the operating system - when you call interrupt 0x80, these values indicate what you want it to do. – Leeor Dec 21 '14 at 19:32

1 Answers1

2

You're conflating system call numbers with the system call arguments.

The system call numbers (e.g. "3 = read") are OS-specific (well, kernel-specific), and sometimes version-specific. For example, see the system call numbers for Linux on x86 here and on x86_64 here. How the arguments are passed, how the system call is invoked, and what the system call numbers mean are all architecture- and kernel-specific.

The number "0" for "standard input" on the other hand is a UNIX standardized value, STDIN_FILENO.

nneonneo
  • 171,345
  • 36
  • 312
  • 383
  • 1
    Bam, that's exactly what I was looking for! Thanks :) https://filippo.io/linux-syscall-table/ – Lance Dec 21 '14 at 19:33
  • So does this mean that, for example, this pure assembly [BareMetal OS](https://github.com/ReturnInfinity/BareMetal-OS/tree/master/os) _won't_ have these system call numbers, because it's lower level than that? Whereas Linux or OSX would have their own set of system call numbers, because they have built a much higher layer of abstraction than BareMetal OS (or any other exokernel) has? – Lance Dec 21 '14 at 19:40
  • @LancePollard Yes. The way how to call system is system-specific. The convention that system calls are issued using an `int 0x80` is Linux-specific. For instance: under Windows NT system calls are issued by clients through functions in the `ntdll.dll`. On the lower level they're implemented using `int 0x2E` or `sysenter` instructions. See [Wikipedia: Application Binary Interface](http://en.wikipedia.org/wiki/Application_binary_interface) and [Wikipedia: System call](http://en.wikipedia.org/wiki/System_call) and [Wikipedia: Native API](http://en.wikipedia.org/wiki/Native_API) for some overview – xmojmr Dec 21 '14 at 20:30
  • Thank you, those resources clarified a lot for me. – Lance Dec 21 '14 at 21:08
  • 1
    Follow up question http://stackoverflow.com/questions/27594297/how-to-print-a-string-to-the-terminal-in-x86-64-assembly-nasm-without-syscall – Lance Dec 21 '14 at 22:16