Довольно очевидно, read
возвращает длину в RAX. Это абсолютно нормально для функций и имеет смысл и для макроса.
В этом случае, да, это просто (глючная) оболочка вокруг 32-битного int 0x80
ABI для read()
, который, как объясняет man-страница, возвращает длину. Системные вызовы Linux возвращаются в RAX. Он также странным образом жестко кодирует максимальную длину как 20.
(он глючит, потому что работает только в том случае, если EAX, EBX и EDX уже равны нулю. Он записывает только младшие 16 битов этих регистров перед вызовом 32-битный ABI. Запись полного RCX с адресом бесполезна; int 0x80
использует только младшие 32 бита. Что произойдет, если вы используете 32-битный int 0x80 Linux ABI в 64-битном коде? )
AL
- младший байт RAX, и этот код сохраняет только младший байт длины для печати. ИДК почему они сохраняют его в памяти вместо другого регистра, как нормальный человек. Особенно, когда они копируют всю 64-битную длину в RCX вместо обычного mov ecx, eax
для расширения нуля 32-битного значения в RCX.
Также обратите внимание, что позднее mov ax,1
(32-бит __NR_exit
) рискованно и плохая идея;он потенциально оставляет мусор в старших байтах RAX, приводя к -ENOSYS
вместо _exit(0)
,
При небольшом размере буфера чтение приведет к ошибке (или вернет -EFAULT
, прежде чем он сможет вернуть больше, чем 4096, поэтомув этом случае безопасна замена только младших 16 битов RAX.
Если read
не возвращает отрицательный код ошибки, то эта программа будет аварийно завершать работу вместо выхода, когда последний int 0x80
вернет -ENOSYS
вместовыход.
Попробуйте запустить его с ./a.out <&-
, чтобы закрыть стандартный ввод, приводя к -EBADF
для чтения из стандартного ввода, , а затем сбой.
Кроме того, это64-битный код, поэтому использование 32-битного int 0x80
системного вызова Linux ABI не очень хорошая идея. Некоторые системы Linux (включая WSL) не имеют CONFIG_IA32_EMULATION
и просто ошибаются, как если бы они int 0x81
или любое другое программное прерывание. Что произойдет, если вы используете 32-битный int 0x80 Linux ABI в 64-битном коде?