This recent assembly question got my attention, not for the obviously redundant instructions, but for what the sys_write
outputs.
The program tries to output all 256 ASCII characters and does so beginning with ASCII 48, wrapping around from 255 to 0, and ending with 47.
The output that the asker kindly provides is:
└─$ ./example_displayascii
0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~��������������������������������������������������������������������������������������������������������������������������������
I could accept that the 128 extended ASCII codes were printed that way, but what happened to the codes from 0 to 31, and especially the codes from 32 to 47 that clearly must be printable characters!
My questions:
sys_write
with the (control) codes from 0 to 31?The write()
system call is the same one you use for writing binary data to non-terminal files. POSIX open
/read
/write
/close
are like ISO C fopen
/fread
/fwrite
/fclose
. The C stdio functions just do buffering around the system calls of the same name. (And if any binary vs. text translation happens, which it won't on a POSIX system like GNU/Linux, it's in the C stdio wrappers, not the POSIX system calls.)
This is what the output looks like with stdout connected to the tty in Konsole, KDE's xterm-equivalent terminal emulator in UTF-8 mode, using Monospace 12pt. (Arch GNU/Linux.) XTerm and modern terminal emulators like Konsole and GNOME-Terminal emulate basically a VT-100.
I pressed enter once after running it since it left the cursor not at the start of a line when it exited, so there's whitespace in front of the first prompt bash
printed. I used the mouse to select the prompt and text, but not the final prompt I included in the screenshot; that's why the background is a lighter gray for that part. The bright whitespace to the left of the first prompt after running was not due to mouse selection, that's a real effect of some character.
Copy/pasted as text (of just the mouse selection from the previous image).
peter@volta:/tmp$ ./chars
0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~���������������������������������������������������������������������������������������������������������������������������
▒▒peter@volta:/tmp$
Interesting; even the bright whitespace is copied. I hadn't been expecting that to survive copy/paste and Stack Overflow markdown.
And specifically, what happens when someone terminates a line with the pair 10, 13 instead of the normal 10 only?
Nothing special on a terminal; CR sends the cursor to the leftmost column, but it was already there after an LF (linefeed \n
= 10
).