Использование Аннотации Android - это опция. Это позволит вам просто запустить любой метод в фоновом потоке:
// normal method
private void normal() {
doSomething(); // do something in background
}
@Background
protected void doSomething()
// run your networking code here
}
Обратите внимание, что, хотя он обеспечивает преимущества простоты и удобочитаемости, у него есть свои недостатки.
Есть ряд проблем, которые я вижу:
Итак, вы хотите что-то вроде:
mov [brk_firstloaction], _end
mov rbx, [brk_firstlocation]
add rbx, 0x14 ; space for 5 dwords (20 bytes)
mov rax, 12
int 0x80
Как вы это сделали, вызовите один раз, чтобы извлечь текущее дно кучи, а затем переместите верхнюю часть кучи (что является значением brk). Однако ваш код неверен при использовании 64-битного набора регистров r.x
. Если ваш Linux 32-разрядный (что подразумевается при использовании 45 для номера системного вызова), тогда вы хотите установить 32-битный регистр:
mov eax, 45 ; brk
mov ebx, 0 ; arg 1: 0 = fail returning brk value in rax
int 0x80 ; syscall
mov dword ptr [brk_firstLocation], rax ; save result
mov eax, 45 ; brk
mov ebx, 4 ; arg 1: allocate 4 bytes for a 32-bit int
int 0x80 ; syscall
mov eax, dword ptr [brk_firstLocation] ; reload rax with allocated memory address.
mov dword ptr [eax], 42 ; use result: store 42 in newly allocated storage
Конечно, вы можете повторно загрузить сохраненный значение для повторного использования столько раз, сколько необходимо.
int 80h
предназначен только для 32-битных системных вызовов. Вместо этого используйте syscall
для 64 бит.
Вызов sys_brk дважды избыточен - в сборке вы всегда знаете, где заканчиваются ваши данные программы. Просто поместите там ярлык, и у вас будет адрес.
Выделяя таким образом память менее одной страницы, бессмысленно, она будет распределяться в блоках по 4 КБ в любом случае.
Важно понимать - sys_brk не является функцией управления кучей. Это низкоуровневое управление памятью.
другие указали несколько вещей, которые не соответствуют вашему коду. Я хотел бы добавить, что вы не добавили бы 20 бит к текущей точке останова (или 20 байтов , подобных add rbx, 20
), вы просто добавили бы 5 байтов.
Кроме того, ваш первый аргумент syscall не будет в rbx, он будет в rdi. В 64-битном syscall ABI используются разные номера системных вызовов, разные регистры и другая команда (syscall
вместо int 0x80
), чем 32-разрядная ABI (которая по-прежнему доступна в 64- битных процессов). См. Также wiki wiki x86 для дополнительных ссылок ABI.
Вот как выглядит ваш код:
push rbp
mov rbp, rsp
;; sys_brk(0)
mov rax, 12 ; 12 is SYS_brk (/usr/include/asm/unistd_64.h)
mov rdi, 0 ; rdi for first syscall arg in the 64-bit ABI, not rbx
syscall ; syscall, not int 0x80, for the 64-bit ABI
mov qword [brk_firstLocation], rax
;; sys_brk(old_break + 5)
lea rdi, [rax + 5] ; add 5 bytes to the break point
mov rax, 12
syscall ; set the new breakpoint
На этом этапе вы можете используйте brk_firstLocation как указатель на любую 5-байтовую структуру, которую вы хотите сохранить в куче. Вот как вы могли бы поместить значения в это пространство памяти:
mov rdi, [brk_firstLocation] ; load the pointer from memory, if you didn't already have it in a register
mov byte [rdi], 'A' ; a char at it's first byte
mov [rdi+1], ecx ; a 32-bit value in the last 4 bytes.