Now that we have a binary file (foo.o) it is time to open it with poke. There are two ways to do that.
One way is to pass the name of the file in the poke invocation. The program will start, open the file, and present you with the REPL, like in:
$ poke foo.o [...] (poke)
The other way is to fire up poke without arguments, and then use the
.file
dot-command to open the file:
$ poke [...] (poke) .file foo.o The current IOS is now `./foo.o'. (poke)
Note how poke replies to the dot-command, stating that the current IOS is now the file we opened.
You may be wondering, what is this IOS thing? It is an acronym for Input/Output Space, often written IO Space. This is the denomination used to refer to the entities being edited with poke. In this case the IO space being edited is a file, but we will see that is not always the case: poke can also edit other entities such as memory buffers and remote block-oriented devices over the network. For now, let’s keep in mind that IOS, or IO space, refers to the file being edited.
And why “current”? GNU poke is capable of editing several files (more generally, several IO spaces) simultaneously. At any time, one of these files is the “current one”. In our case, the current IO space is the file foo.o, since it is the only file poke knows about:
(poke) .info ios Id Type Volatile Mode Bias Size Name * 0 FILE no rw 0x00000000#B 0x00000398#B ./foo.o
The command .info ios
gives us information about all the IO
spaces that are currently open. The first column tells us a positive
integer that identifies the IOS. This IO space identifier is
unique at any given time. In this example, the id corresponding to
foo.o is 0
. The second column tells us the type of IO
space. The third column tells us whether the IO space is
volatile or not; the contents of a volatile IO space can change
at any time out of our control. The third column tells us that
foo.o allows both reading and writing. The fourth column tells
us the size of the file, in hexadecimal. The fifth column is the name
of the IO space; in this case, it is the path to the file being
edited.
You may wonder what is that weird suffix #B
. It is a unit,
and tells us that the size 0x398
is measured in bytes, i.e. the
size of foo.o is 0x398
bytes (or, in decimal, 920
bytes.)
Finally, the asterisk character at the left of the entry for foo.o identifies it as the current IO space. To see this more clearly, let’s open another file:
(poke) .file/r bar.o The current IOS is now `./bar.o'. (poke) .info ios Id Type Volatile Mode Bias Size Name * 1 FILE no r 0x00000000#B 0x00000398#B ./bar.o 0 FILE no rw 0x00000000#B 0x00000398#B ./foo.o
Ah, there we have both foo.o and bar.o. Note how
bar.o is opened in read-only mode rather than read-write. This
is because we used the /r
flag when invoking the
.file
dot-command. In poke it is important to open files in
read-only mode if we don’t plan to update them, because the program
can work much faster.
Now the current
IO space (the entry featuring the asterisk at the left) is the file
that we just opened, bar.o. This is because poke always sets
the most recently open file as the current one. We can switch back to
foo.o using yet another dot-command, .ios
, which gets
an IO space as an argument:
(poke) .ios 0 The current IOS is now `./foo.o'. (poke) .info ios Id Type Volatile Mode Bias Size Name 1 FILE no r 0x00000000#B 0x00000398#B ./bar.o * 0 FILE no rw 0x00000000#B 0x00000398#B ./foo.o
We are back to foo.o. Since we are not really interested in bar.o, let’s close it:
(poke) .close 1 (poke) .info ios Id Type Volatile Mode Bias Size Name * 0 FILE no rw 0x00000000#B 0x00000398#B ./foo.o
Note how in the examples above we used the IO space identifiers (0 and
1) in order to refer to them. This can be inconvenient, as these ids
are not memorable at all. Fortunately it is also possible to refer to
an IO space by name using the $<name>
construct, like
this:
(poke) .ios $<./foo.o> The current IOS is now `./foo.o'. (poke) .close $<./bar.o>
Note that the $<name>
construct in lenient in the sense
that it will accept any non-empty sub string that identifies an
existing IO space in an unambiguous way. This is useful in order to
avoid having to write annoying paths. For example:
(poke) .file /bin/ls (poke) .file /bin/cat (poke) .ios $<ls> The current IOS is now `/bin/ls'.
Auto completion also works. Try it!