I think I know how to handle this case, but I just want to make sure I have it right. Say you have the following C code:
int myInt = 3;
int* myPointer = &myInt;
int** mySecondPointer = &myPointer;
P contains an address that points to a place in memory which has another address. I'd like to modify the second address. So the MIPS code:
la $t0, my_new_address
lw $t1, ($a0) # address that points to the address we want to modify
sw $t0, ($t1) # load address into memory pointed to by $t1
Is that the way you would do it?
Yes, that's correct as far as I can tell. It would have been easier if you used the same variable names (e.g. symbols instead of hard register names).
Why haven't you simply compiled the c-code and took a look at the list-file or assembly-output? I always do that when in doubt.
Related
I have the following piece of ARM Assembly Code from my professor.
I do not understand why i need to move the stack pointer to r1 and what happens exactly.
I know from the lecture, that ...
The stack pointer is pointing to the last written value on the stack.
Does pointing to always mean that the address is stored?
I managed to get the code working. But i want to improve code quality and understand what's going on. Also i am not allowed to use arithmetic operations anywhere in the program.
i tried the debugger also. but i only figured out how to watch the program counter from there.
I used
info registers sp pc
and
disas
I searched through all the options of the debugger but could not find something helpful.
In the stack pointer register is stored - i guessed - some address value.
// scan for users answer 'y'
ldr r0, =charplace
mov r1, sp # ???
bl scanf # Scan user's answer
ldr r1, =yes # Put address of 'y' in r1
ldrb r1, [r1] # Load the actual character 'y' into r1
at the start of the main function i do this:
.global main
main:
push {r4 - r7, lr} # copy values of these reg on top of the stack
sub sp, sp, #4 # needs to be replaced ! TODO
and at the end this:
end: add sp, sp, #4 # needs to be replaced ! TODO
pop {r4 - r7, pc} # copy values from the top of the stack back into these registers
The sub sp, sp, #4 allocates 4 bytes of space for a buffer. With a full descending stack, sp will point to the start of that buffer, with the other 3 bytes being at sp+1, sp+2, and sp+3 of course. The reason to move sp to r1 is that scanf needs the buffer address as second argument and r1 is used to pass that.
In gdb you can examine memory using the x command, to see the stack you can do for example x/4x $sp. See help x for format specifiers.
How can i recognize in llvm taking the address of variable. For example:
int g;
int *v;
int *test() {
v = &g
func(&g)
return &g
}
In LLVM is getting address:
store i32* #g, i32** #v, align 4
call i32 #func(i32* #g)
ret i32* #g
I want to recognize if the address is taken or the value of variable is taken. Thanks for the answers.
There isn't going to be a way to tell this in general. Taking the address of a certain things might be optimized away in certain instances. The compiler might choose to pass some things by pointer even though it wasn't written that way.
You might have better luck using libclang an operating on the c++ syntax tree, I think this is possible.
I have been asked to provide a solution to the following question;
1.A) In MIPS assembly, there are many ways of copying the contents of one register into another register, using only one instruction. Write five single instructions, which each copy the contents of $s0 into $s1. You cannot use MIPS pseudo-instructions.
I have worked out the following solutions, however I am unable to find a way to "mark" them so please reply if there are "easier" ways or if you think any of the following are wrong;
add $s1, $s0, $zero
addi $s1, $s0, 0
sub $s1, $s0, $zero
lw $s1, 0($s0)
and $s1, $s0, $zero
As a further point I also have the following question, which has completely thrown me, mainly due to the double ^ involved;
1.B) If we execute the following grep command:
grep -E "^[^a][bc].*"
Which of the following lines (typed on the console) will be matched?
abc
AbX
Zc
ZcHello
aBNo
bb
bDbc
bca
cba
bbbbb
Any help is of course greatly appreciated.
4 out of 5 look fine to me.
However the operation:
lw $s1, 0($s0)
does not do what you want. The X(REG) syntax does indirect addressing. Let's say that $s0 contains 1165. In this case, lw $s1, 0($s0) would put into $s1 the value stored at memory address 1165. lw $s1, 4($s0) would put the value at memory address 1169 into $s0.
Hopefully that's clear. If not, you can google indirect addressing, or ask, and I'll try to explain it better.
If you want to test out MIPS code, there's an excellent java based MIPS simulator that lets you 'inspect' the state of the cpu, step through your program, etc:
http://courses.missouristate.edu/kenvollmar/mars/
Unfortunately I'm no grep expert so I can't help you there. As with any UNIX program, take a look at the manpage and help message:
man page:
man grep
help message:
grep --help
Hope this helps!
i was reading an example in assembly languaje, and i have a little doubt. We were using assembly only on our programs, but the last unit on the semester it's to merge it with turbo c (in-line assembly), and reading the code, there's a part which i don't quite get it:
Here's the assembly part:
dosseg
.model small
.code
public _myputchar
_myputchar PROC
push bp
mov bp,sp
mov dl,[bp+4]
mov ah,2
int 21h
pop bp
ret
_myputchar ENDP
END
And here's the C part:
#include<stdio.h>
extern void myputchar( char x );
char *str={"Hola Mundo\n"};
void main ( void )
{
while(*str)
myputchar(*str++);
getchar();
}
So, it's pretty straight forward, and the program works, but, what i don't get, it's the assembly code. The problem is, Why the base pointer (bp) it's pointing to +4? (mov dl,[bp+4]), I would think that you only had to mov dl,bp but i don't get why +4. If someone can help we, that would be really apretiated!. (in the include section i put the "" Because the formating tools it's giving me such headech -_-!
The argument (x) is pushed onto the stack before calling the function. After this, the call instruction will push the return address (2 bytes in this case) onto the stack, and the push bp at the beginning of the function will push another 2 bytes onto the stack.
So by now you've pushed 2+2 == 4 more bytes onto the stack after the argument. Since the stack grows downward that means that to get the argument you have to offset the pointer by +4 bytes.
The starting address of the string you want to print is at [bp + 4]. The current stack pointer is [bp]. Remember, the stack grows down.
Not used memcpy much but here's my code that doesn't work.
memcpy((PVOID)(enginebase+0x74C9D),(void *)0xEB,2);
(enginebase+0x74C9D) is a pointer location to the address of the bytes that I want to patch.
(void *)0xEB is the op code for the kind of jmp that I want.
Only problem is that this crashes the instant that the line tries to run, I don't know what I'm doing wrong, any incite?
The argument (void*)0xEB is saying to copy memory from address 0xEB; presumably you want something more like
unsigned char x = 0xEB;
memcpy((void*)(enginebase+0x74c9d), (void*)&x, 2);
in order to properly copy the value 0xEB to the destination. BTW, is 2 the right value to copy a single byte to program memory? Looks like it should be 1, since you're copying 1 byte. I'm also under the assumption that you can't just do
((char*)enginebase)[0x74c9d] = 0xEB;
for some reason? (I don't have any experience overwriting program memory intentionally)
memcpy() expect two pointers for the source and destination buffers. Your second argument is not a pointer but rather the data itself (it is the opcode of jnz, as you described it). If I understand correctly what you are trying to do, you should set an array with the opcode as its contetns, and provide memcpy() with the pointer to that array.
The program crashes b/c you try to reference a memory location out of your assigned space (address 0xEB).