Syscall 2 открывает файл.
Параметры:
rax: syscall #2
rdi: pointer: zero terminated filename
rsi: int: flags
rdx: int: mode
Вы можете использовать следующий код:
...
mov rax, 2 //syscall_2 = open file
...
syscall
До сих пор так хорошо, однако, в соответствии с документацией:
Учитывая путь для файл, open() возвращает дескриптор файла, небольшое неотрицательное целое число для использования в последующих системных вызовах.
Итак, вы только сделали первую часть, вы, надеюсь, получили дескриптор файла, с этим вы можете считывать данные из файла, вам нужно добавить эту часть кода.
Наконец, когда вы закончите, вам нужно очистить после себя и закрыть файл.
Позвольте мне заполнить для вас код.
//********* get a file_descriptor.
push r15 //save non-volatile registers
push r14
mov eax,2 //syscall_2 = open file
mov rdi,[file_1] //filename
xor esi,esi //flags = O_RDONLY
xor edx,edx //mode = 0, good habits: don't leave parameters undefined.
syscall //get me a file descriptor (fd).
test eax,eax //is the fd positive?
mov edi,eax //param1=fd
mov eax,1 //set failure code, just in case.
js failure //no,it's negative,report failure.
//*********** read some data
//Step 2, we have a fd, lets read the data in the file.
mov r15,rax //save the fd in a non-volatile register for later.
xor eax,eax //syscall_0 = read data from file
mov rsi,[buffer] //an array to place the data into
//`buffer` is the pointer to the buffer.
mov edx,[len] //the max_len of the buffer, must be >= 2.
dec edx //keep an extra byte to put a zero terminator into.
//put 2 zero's if you're reading unicode_16 data.
syscall //Read that data.
xor r14,r14 //assume a length of zero in case of failure.
//we can't jump to failure, we still need to clean up!
test eax,eax //do we have a fail?
cmovs rax,r14 //if failure, then set zero length result, else do nothing.
mov [len],eax //set len to the length of data read.
mov byte ptr [buffer+eax],0 //add a zero byte to terminate the data.
//************ clean up
//we are done, got the data. Let's close the file.
mov r14,rax //if rax=0 then we had an error, store for later use
mov rdi,r15 //param1 = fd
mov eax,3 //syscall_3: close file
syscall //close that file.
test eax,eax //did close go ok?
mov eax,3 //set failure code just in case.
js failure //negative = failure
//************ report back
//if we get here, all went ok, report success and return.
xor eax,eax //return 0 for success.
//we still need to check if `read()` failed.
sub r14,1 //carry = 1 only if r14 = 0 = failure else carry = 0
//sub eax,(0+carry) //if success then no-op else eax=eax-1
sbc eax,eax //eax = -1 if we had a failure when reading.
failure:
pop r14 //restore non-volatile registers
pop r15
ret //all done
Около 64 бит против 32 бита
Также я прочитал, что мы имеют 32 бит операнда-источник [...]
Это полное и абсолютное фигню.
X64 - это полноценный 64-битный процессор, который делает то, что говорит на жестяной основе.
Если используется 64-битный регистр (регистр любой, который начинается с R
(и не заканчивается с d
или b
)) использовать все 64 бита в этом регистре.
Указатели на память должны всегда перейдите в регистр 64 бит R
.
Если регистр начинается с E
(или заканчивается d
), это 32-разрядный регистр (нижние 32 бита).
Любая операция записи в 32-битном регистре содержит нулевые верхние 32 бита перекрытого 64-битного регистра, например. mov eax,1
комплекты rax
- 1; mov eax,-1
комплектов rax
до $0000 0000 FFFF FFFF
;
mov eax,2
и mov rax,2
делать то же самое.
За исключением того, что mov eax,2
на два байта короче и, следовательно, является предпочтительным.
Если вы читаете/записываете из/в память, операция будет соответствовать размеру регистра, если вы не укажете иное.
Если вы пишете немедленно в память, вы должны указать размер.
Вы не можете записать 64-разрядную оперативную память в память, вам нужно будет использовать 2 инструкции для этого: mov R64,imm64 + mov [mem],R64
.
Caveat
Любой запись в 16-ти бит или 8 бит регистр делает не ноля из верхней части соответствующих бит 32/64 регистра!
Заключение
Если вы хотите написать сборку, вам нужно на самом деле узнать сборку с нуля.
Поскольку вы программируете в Linux, я рекомендую получить копию книги Джеффа Дунтемана: Assembly Language Step By Step, for Linux
Джефф - легенда и может объяснить сборку лучше всех на этой планете.
Как это связано с QuickTime? 'ESI' - 32-битная, а не 64-разрядная. Вы должны исправить код сборки, чтобы вместо этого использовать 64-разрядный регистр. Почему вы XOR'ing ESI с собой? На основании кода, который вы предоставили, ничего не содержится в ESI –
изменено, было ошибкой. –
Ваш код сборки все еще неверен. –