для моей работы я должен инвертировать то, что делает эта часть кода (ARM9). Я - разработчик Java, и я действительно не понимаю эту часть кода, связанного с единственной функцией.
Конечно, я прошу помогать, потому что исходный код не более доступен. Кто-либо может помочь мне знать то, что этот код делает с маленьким алгоритмом на каком-либо высоком языке? Это было бы хорошо. Я пробовал в течение многих часов без результатов.
sub_FFFF7B38
PUSH {LR}
ADDS R2, R0, #0
LDRB R3, [R2]
CMP R3, #0
BEQ loc_FFFF7B52
SUBS R1, #1
BCC loc_FFFF7B52
loc_FFFF7B46:
ADDS R0, #1
LDRB R3, [R0]
CMP R3, #0
BEQ loc_FFFF7B52
SUBS R1, #1
BCS loc_FFFF7B46
loc_FFFF7B52:
SUBS R0, R0, R2
POP {R1}
За исключением двух последних строк, это может быть что-то вроде следующего.
Пожалуйста, не бейте меня, если я ошибаюсь на 100%.
Если
R0
равно p0
или p
, а
R1
равно n
и
R2
] - временное значение (отредактировано; сначала я подумал: i
или адрес p0 [i]
)
R3
- временное значение
.
sub_FFFF7B38
PUSH {LR} ; save return address
ADDS R2, R0, #0 ; move R0 to R2
LDRB R3, [R2] ; load *p0
CMP R3, #0 ; if *p0==0
BEQ loc_FFFF7B52 ; then jump to loc_FFFF7B52
SUBS R1, #1 ; decrement n
BCC loc_FFFF7B52 ; if there was a borrow (i.e. n was 0): jump to loc_FFFF7B52
loc_FFFF7B46:
ADDS R0, #1 ; increment p
LDRB R3, [R0] ; load *p
CMP R3, #0 ; if *p==0
BEQ loc_FFFF7B52 ; jump to loc_FFFF7B52
SUBS R1, #1 ; decrement n
BCS loc_FFFF7B46 ; if there was no borrow (i.e. n was not 0): jump to loc_FFFF7B46
loc_FFFF7B52:
SUBS R0, R0, R2 ; calculate p - p0
POP {R1} ; ??? I don't understand the purpose of this
; isn't there missing something?
или в C:
int f(char *p0, unsigned int n)
{
char *p;
if (*p0==0 || n--==0)
return 0;
for(p=p0; *++p && n>0; n--)
{
}
return p - p0;
}
Да. Присвоение Placemark имени и описания сделает его кликаемым объектом в Google Earth и откроется с информационным окном, в котором будут показаны оба объекта. Вы можете создать ролловер/mouseover поведение, используя карты стилей, вот пример, который делает оба:
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document>
<name>Highlighted Icon</name>
<description>Place your mouse over the icon to see it display the new
icon</description>
<StyleMap id="exampleStyleMap">
<Pair>
<key>normal</key>
<!-- you could also use a <styleUrl> here instead of inlining -->
<Style>
<PolyStyle>
<color>7dff0000</color>
</PolyStyle>
</Style>
</Pair>
<Pair>
<key>highlight</key>
<!-- you could also use a <styleUrl> here instead of inlining -->
<Style>
<PolyStyle>
<color>7dffffff</color>
</PolyStyle>
</Style>
</Pair>
</StyleMap>
<!-- and now, a Placemark that uses the StyleMap -->
<Placemark>
<name>Roll over this polygon</name>
<description>this will show up when clicked</description>
<visibility>1</visibility>
<styleUrl>#exampleStyleMap</styleUrl>
<Polygon>
<tessellate>1</tessellate>
<altitudeMode>absolute</altitudeMode>
<outerBoundaryIs>
<LinearRing>
<coordinates>
-112.3372510731295,36.14888505105317,1784
-112.3356128688403,36.14781540589019,1784
-112.3368169371048,36.14658677734382,1784
-112.3384408457543,36.14762778914076,1784
-112.3372510731295,36.14888505105317,1784
</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
</Document>
</kml>
-121--4779920- я думаю, что вы хотите определить функцию сравнения, где вы можете определить ранг между любыми 2 предметами в списке.
int CompareObject1(Object1 left, Object1 right)
{
// TODO: cases where your items are null
// compare Property1 values
if (left.Property1)
{
if (right.Property1)
{
// items at same rank
return 0;
}
else
{
// left item is higher rank than right
return -1;
}
}
else if (right.Property1)
{
// right item is higher rank than left
return 1;
}
// Property1 doesn't indicate position, move along
// TODO: repeat for Property2
// Property2 doesn't indicate position, move along
// TODO: repeat for Property3
// if we get here, no determination can
// be made/don't bother to move anything
return 0;
}
возвращаемое значение указывает, должен ли левый или правый объект быть ранжирован выше с -1 или 1 (или 0 для предпочтения). просто убедитесь, что вы покрываете все ваши условия.
тогда вы можете использовать это как
List<Object1> foo = new List<Object1>() { <items...> };
foo.Sort(CompareObject1);
, если вы список заканчивается назад, я, вероятно, перевернул знаки в функции сравнения. ваши правила сортировки противоречивы, поэтому я позволю вам сортировать Property2 и Property3.
-121--3594855- Мой ASM немного ржавый, поэтому никаких гнилых помидоров, пожалуйста. Предположим, что это начинается с sub _ FFFF7B38
:
Команда PUSH {LR}
заповедников регистр линии связи, который представляет собой специальный регистр, содержащий обратный адрес во время вызова подпрограммы.
ДОБАВЛЯЕТ
наборов флагам (например, CMN
). Также ADD R2, R0, # 0
добавляет R0
к 0 и хранению в R2. (Исправление от Чарльза в комментариях)
LDRB R3, [R2]
загружает содержимое R2
в основную память вместо регистра, на который ссылается R3
. LDRB
загружает только один байт. Три неиспользуемых байта в слове обнуляются при загрузке. В основном, получение R2
из регистров и в безопасном хранении (может быть).
CMP R3, # 0
выполняет вычитание между двумя операндами и устанавливает флаги регистра, но не сохраняет результат. Эти флаги ведут к...
BEQ loc_FFFF7B521
, что означает «Если предыдущее сравнение было равно, перейти к loc_FFFF7B521» или если (R3 = 0) {перейти к loc_FFFF7B521;}
So, если R3
не равно нулю, то команда SUBS R1, # 1
вычитает один из R1
и устанавливает флаг.
BCC loc_FFFF7B52
вызовет переход к loc _ FFFF7B52
, если флаг переноса набора.
(snip)
Наконец, POP {LR}
восстанавливает предыдущий обратный адрес, который содержался в регистре ссылки до выполнения этого кода.
Edit - Пока я был в машине, Керд писал о том, о чем я думал, когда пытался написать свой ответ и у меня не было времени.
Как насчет этого: Набор инструкций для ARM
Некоторые подсказки / упрощенный asm
X:
или: Неважно:
означает, что следующее является «подпрограммой». Вы когда-нибудь использовали "goto" в Java? На самом деле похоже на это.
Если у вас есть следующее (игнорируйте, если это правильный arm-asm, это просто псевдоним):
PUSH 1
x:
POP %eax
Сначала он помещает 1 в стек, а затем помещает его обратно в eax (что является сокращением от расширенного топора, который является регистр, в который можно поместить 32-битный объем данных)
Что же тогда делает x:
? Что ж, предположим, что до этого также есть 100 строк asm, тогда вы можете использовать инструкцию "jump" для перехода к x:
.
Это небольшое введение в asm. Упрощенный.
Попытайтесь понять приведенный выше код и изучить набор инструкций.
Филип предоставил несколько указателей, вам также необходимо ознакомиться с соглашением о вызовах ARM. (То есть, какие регистры содержат аргументы функции при входе, а какие - ее возвращаемое значение.)
После быстрого чтения я думаю, что этот код является strnlen или чем-то тесно связанным с ним.
Вот инструкции, прокомментированные строка за строкой
sub_FFFF7B38
PUSH {LR} ; save LR (link register) on the stack
ADDS R2, R0, #0 ; R2 = R0 + 0 and set flags (could just have been MOV?)
LDRB R3, [R2] ; Load R3 with a single byte from the address at R2
CMP R3, #0 ; Compare R3 against 0...
BEQ loc_FFFF7B52 ; ...branch to end if equal
SUBS R1, #1 ; R1 = R1 - 1 and set flags
BCC loc_FFFF7B52 ; branch to end if carry was clear which for subtraction is
; if the result is not positive
loc_FFFF7B46:
ADDS R0, #1 ; R0 = R0 + 1 and set flags
LDRB R3, [R0] ; Load R3 with byte from address at R0
CMP R3, #0 ; Compare R3 against 0...
BEQ loc_FFFF7B52 ; ...branch to end if equal
SUBS R1, #1 ; R1 = R1 - 1 and set flags
BCS loc_FFFF7B46 ; loop if carry set which for subtraction is
; if the result is positive
loc_FFFF7B52:
SUBS R0, R0, R2 ; R0 = R0 - R2
POP {R1} ; Load what the previously saved value of LR into R1
; Presumably the missing next line is MOV PC, R1 to
; return from the function.
Итак, в самом простом коде C:
void unknown(const char* r0, int r1)
{
const char* r2 = r0;
char r3 = *r2;
if (r3 == '\0')
goto end;
if (--r1 <= 0)
goto end;
loop:
r3 = *++r0;
if (r3 == '\0')
goto end;
if (--r1 > 0)
goto loop;
end:
return r0 - r2;
}
Добавление некоторых управляющих структур, чтобы избавиться от goto
s:
void unknown(const char* r0, int r1)
{
const char* r2 = r0;
char r3 = *r2;
if (r3 != '\0')
{
if (--r1 >= 0)
do
{
if (*++r0 == '\0')
break;
} while (--r1 >= 0);
}
return r0 - r2;
}
Edit: Теперь, когда моя путаница с битом переноса и SUBS
прояснилась, это имеет больше смысла.
Упрощение:
void unknown(const char* r0, int r1)
{
const char* r2 = r0;
while (*r0 != '\0' && --r1 >= 0)
r0++;
return r0 - r2;
}
На словах это поиск индекса первого NUL
в первых r1
символах указателя строки на r0
или вернуть r1
, если нет.