ARM assembly addition - linux

I'm trying to get modulo of addition of two numbers with ARM 32-bit processor. Well, I'm trying to make it with three unsigned long 128 bit numbers but I cant succeed. Can anyone give me an idea or basic example of it?
mov r1, #11
mov r2, #13
mov r3, #15
add r1, r1,r2
subge r1, r1, r3
ldr lr, address_of_return2
ldr lr, [lr]
bx lr

You need cmp r1,r3 between add and subge. First add, than test if greater than modulo, finally substract if greater or equal (assuming both input numbers are less than modulo).
PS: Or cmp r3,r1.... not sure by the order right now.

Related

What's the meaning of mov 0x8(%r14,%r15,8),%rax

In here what's the meaning of 0x8(%r14,%r15,8), I know 0x8(%r14,%r15,8) is SRC, but I don't understand why use two register %r14 and %r15 in here, and I don't understand how to cal the src address.
Thanks so much for any input.
Information pulled from http://flint.cs.yale.edu/cs421/papers/x86-asm/asm.html
AT&T Addressing:
Memory Address Reference: Address_or_Offset(%base_or_offset, %Index_Register, Scale)
Final Address Calculation: Address_or_Offset + %base_or_offset + [Scale * %Index_Reg]
Example:
mov (%esi,%ebx,4), %edx /* Move the 4 bytes of data at address ESI+4*EBX into EDX. */

Compare user-inputted string/character to another string/character

So I'm a bit of a beginner to ARM Assembly (assembly in general, too). Right now I'm writing a program and one of the biggest parts of it is that the user will need to type in a letter, and then I will compare that letter to some other pre-inputted letter to see if the user typed the same thing.
For instance, in my code I have
.balign 4 /* Forces the next data declaration to be on a 4 byte segment */
dime: .asciz "D\n"
at the top of the file and
addr_dime : .word dime
at the bottom of the file.
Also, based on what I've been reading online I put
.balign 4
inputChoice: .asciz "%d"
at the top of the file, and put
inputVal : .word 0
at the bottom of the file.
Near the middle of the file (just trust me that there is something wrong with this standalone code, and the rest of the file doesn't matter in this context) I have this block of code:
ldr r3, addr_dime
ldr r2, addr_inputChoice
cmp r2, r3 /*See if the user entered D*/
addeq r5, r5, #10 /*add 10 to the total if so*/
Which I THINK should load "D" into r3, load whatever String or character the user inputted into r2, and then add 10 to r5 if they are the same.
For some reason this doesn't work, and the r5, r5, #10 code only works if addne comes before it.
addr_dime : .word dime is poitlessly over-complicated. The address is already a link-time constant. Storing the address in memory (at another location which has its own address) doesn't help you at all, it just adds another layer of indirection. (Which is actually the source of your problem.)
Anyway, cmp doesn't dereference its register operands, so you're comparing pointers. If you single-step with a debugger, you'll see that the values in registers are pointers.
To load the single byte at dime, zero-extended into r3, do
ldrb r3, dime
Using ldr to do a 32-bit load would also get the \n byte, and a 32-bit comparison would have to match that too for eq to be true.
But this can only work if dime is close enough for a PC-relative addressing mode to fit; like most RISC machines, ARM can't use arbitrary absolute addresses because the instruction-width is fixed.
For the constant, the easiest way to avoid that is not to store it in memory in the first place. Use .equ dime, 'D' to define a numeric constant, then you can use
cmp r2, dime # compare with immediate operand
Or ldr r3, =dime to ask the assembler to get the constant into a register for you. You can do this with addresses, so you could do
ldr r2, =inputVal # r2 = &inputVal
ldrb r2, [r2] # load first byte of inputVal
This is the generic way to handle loading from static data that might be too far away for a PC-relative addressing mode.
You could avoid that by using a stack address (sub sp, #16 / mov r5, sp or something). Then you already have the address in a register.
This is exactly what a C compiler does:
char dime[4] = "D\n";
char input[4] = "xyz";
int foo(int start) {
if (dime[0] == input[0])
start += 10;
return start;
}
From ARM32 gcc6.3 on the Godbolt compiler explorer:
foo:
ldr r3, .L4 # load a pointer to the data section at dime / input
ldrb r2, [r3]
ldrb r3, [r3, #4]
cmp r2, r3
addeq r0, r0, #10
bx lr
.L4:
# gcc greated this "literal pool" next to the code
# holding a pointer it can use to access the data section,
# wherever the linker ends up putting it.
.word .LANCHOR0
.section .data
.p2align 2
### These are in a different section, near each other.
### On Godbolt, click the .text button to see full assembler directives.
.LANCHOR0: # actually defined with a .set directive, but same difference.
dime:
.ascii "D\012\000"
input:
.ascii "xyz\000"
Try changing the C to compare with a literal character instead of a global the compiler can't optimize into a constant, and see what you get.

Xbox 360, PPC function Hook crashes when i call a function in the hook. PowerPC

i am facing a problem that I could not resolve so i have to turn to the community to help me out. The problem is related to PPC function hooking.
The area where i am hooking is this.
.text:8220D810 mflr r12
.text:8220D814 bl __savegprlr_20
.text:8220D818 stfd f31, var_70(r1)
.text:8220D81C stwu r1, -0x100(r1)
.text:8220D820 lis r11, off_82A9CCC0#ha // => This is where i am hooking the function
.text:8220D824 lis r22, dword_82BBAE68#ha // These 4 instructions are overwritt
.text:8220D828 lis r10, 8 # 0x87700 //Patched
.text:8220D82C mr r26, r3 //Patched
.text:8220D830 li r20, 0
.text:8220D834 lwz r9, off_82A9CCC0#l(r11)
.text:8220D838 ori r23, r10, 0x7700 # 0x87700
.text:8220D83C lwz r11, dword_82BBAE68#l(r22)
.text:8220D840 cmplwi cr6, r11, 0
.text:8220D844 stw r9, 0x100+var_7C(r1)
.text:8220D848 bne cr6, loc_8220D854
.text:8220D84C mr r30, r20
.text:8220D850 b loc_8220D85C
Here it jumps to my code cave that is mentioned below. The patched instructions are correctly written in the PredictPlayerHook function and is not the problem.
The problem here is if i call a function in the hook e.g here i call "GetCurrentCmdNumber(0);" it causes the game to crash. Now without calling any functions the game doesn't crash and the code cave works without any issues. but if I try to call any function within the code cave(PredictPlayerHook) it just crashes. I cant debug it so i dont know where it crashes.
void __declspec(naked) PredictPlayerHook(){
DWORD R11,Return,cmdNumber;
__asm lis r11, 0x82AA //patched instructions
__asm lis r22, 0x82BC //patched instructions
__asm lis r10, 0x8 //patched instructions
__asm mr r26, r3 //patched instructions
__asm mflr r0 ; //mflr grabs the link register, and stores it into the first operand. r0 is now the link register
__asm stw r0, -0x14(r1) ; //Save the link register inside the stack frame
__asm stwu r1, -0x90(r1) ;// This is pushing the stack (hence push)
// cmdNumber = GetCurrentCmdNumber(0);
__asm addi r1, r1, 0x90 ;//popping the stack frame
__asm lwz r0,-0x14(r1) ; //Reading the link register from the sack
__asm mtlr r0
__asm stw r11,R11
//Return = 0x82200230;
__asm lis r11,0x8220 //Return Address is correct. The difference is in IDA segment, it is +0xD600 ahead of the original address.
__asm ori r11,r11,0x0230
__asm mtctr r11
__asm lwz r11,R11
__asm bctr
}
Here is the function itself and its correct. I can use it in a hook placed else where in the game so it has no issues.
typedef int (__cdecl* CL_GetCurrentCmdNumber)(int localClientNum);
CL_GetCurrentCmdNumber GetCurrentCmdNumber = (CL_GetCurrentCmdNumber)0x82261F90;

How to increment a letter in string in lc3?

I am writing an LC3 program that increments each letter of a three-letter word stored in memory following the program. 'a' becomes 'd', 'n' becomes 'q', 'z' becomes 'c', etc.
I am using this as LC3 Assembly a reference
Here is my code so far
.orig x3000
ADD R1, R1, #3
LEA R2, STRING
HALT
STRING .STRINGZ "anz"
.END
I was able to figure out how to declare a string of characters in LC3 from my reference. However does anyone how to do the actual incrementation or have any references that I could use to figure out how to do it?
Using a while loop, I was able to get it to increment each char of the string until a null value is found. I didn't code it to loop back around (z becoming c) but this should get you started.
;tells simulator where to put my code in memory(starting location). PC is set to thsi address at start up
.orig x3000
MAIN
AND R1, R1, #0 ; clear our loop counter
WHILE_LOOP
LEA R2, STRING ; load the memory location of the first char into R1
ADD R2, R2, R1 ; Add our counter to str memory location. R2 = mem[R1 + R2]
LDR R3, R2, #0 ; Loads the value stored in the memory location of R2
BRz END_WHILE ; If there is no char then exit loop
ADD R3, R3, #3 ; change the char
STR R3, R2, #0 ; store the value in R3 back to the location in R2
ADD R1, R1, #1 ; add one to our loop counter
BR WHILE_LOOP ; jump to the top of our loop
END_WHILE
HALT
; Stored Data
STRING .STRINGZ "anz"
.END

Using relative values in array sorting ( asm )

I need to sort through an array and sort each individual row in array to be in ascending order. I doesn't seem to going so well (surprise!) as I keep getting hit with two errors:
a2101: cannot add two relocatable labels
and
a2026: constant expected
Here's my sort, it makes sense to me, but I think I'm still trying to implement high-lvl language techniqes into assembly. Is there a way to get around not being able to use relative values? (the array is 7 rows by 9 columns, btw).
mov cx, 7; cx = number of rows
outer: ; outer loop walk through the rows
push cx
mov cx, 9
mov row, cx ;rows
middle: ; middle-loop walk through the columns
push cx
sub cx, 1 ;cx = cx-1
mov column, cx ;columns
inner: ;inner loop - compare and exchange column values
cmp mArray[row*9 + column], mArray[row*9 + column+1]
xchg mArray[row*9 + column+1], mArray[row*9 + column]
; compare and exchange values from mArray table
inc column
loop inner
pop cx
loop middle ;end middle loop
pop cx
loop outer ; end outer loop
ret
Thanks for any help.
The following lines are problematic:
cmp mArray[row*9 + column], mArray[row*9 + column+1]
xchg mArray[row*9 + column+1], mArray[row*9 + column]
Unlike HLL, assembly does NOT allow for arbitrary expressions in place of constants or variables. That's why HLL's were invented in the first place. Calculate the offset in the registers before using:
mov ax, row
mov bx, ax
shr bx, 3 ; bx = row*8 now
add bx, ax ; bx = row*9 now
add bx, column ; bx = row*8+column now
mov dx, [bx] ;first comparand
inc bx
cmd dx, [bx] ; that's your compare!
Also, you don't use any branching; the cmp instruction is utterly pointless; you waste its result, and xcng is not executed conditionally. Read up on conditional jump commands (jz/jnz etc.).
Also, I seriously hope this is an exercise, not a real project. If it's for real, please reconsider using assembly. For something as trivial as this, assembly is a wrong, wrong choice. Espec. considering how bad you are at it.

Resources