Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Shen, Siran
arm11_
Commits
bc1e11fd
Commit
bc1e11fd
authored
Jun 04, 2020
by
sea19
Browse files
Execute part not working properly but getting close
parent
dc021ed2
Changes
2
Expand all
Hide whitespace changes
Inline
Side-by-side
src/emulate.c
View file @
bc1e11fd
This diff is collapsed.
Click to expand it.
src/instructionPart.c
View file @
bc1e11fd
...
...
@@ -6,14 +6,14 @@
#include <stdio.h>
#include <stdlib.h>
#define NREGS 1
6
#define STACK_SIZE
1024
#define NREGS 1
7
#define STACK_SIZE
65536
#define PC 15
struct
arm_state
{
unsigned
int
regs
[
NREGS
];
unsigned
char
memory_stack
[
STACK_SIZE
];
int
n
,
z
,
k
,
v
;
int
n
,
z
,
c
,
v
;
};
// for tests and analysis
...
...
@@ -27,14 +27,25 @@ struct emu_analysis_struct {
int
branches_not_taken
;
};
void
set_flag
(
int
n
,
int
z
,
int
k
,
int
v
,
struct
arm_state
*
state
)
{
state
->
n
=
n
;
state
->
z
=
z
;
state
->
k
=
k
;
state
->
v
=
v
;
void
arm_state_init
(
struct
arm_state
*
as
,
unsigned
int
*
objectCode
)
{
/* zero out all arm state */
state
->
z
=
0
;
state
->
n
=
0
;
state
->
p
=
0
;
for
(
int
i
=
0
;
i
<
NREGS
;
i
++
)
{
as
->
regs
[
i
]
=
0
;
}
for
(
int
i
=
0
;
i
<
STACK_SIZE
;
i
++
)
{
as
->
stack
[
i
]
=
0
;
}
as
->
regs
[
PC
]
=
objectCode
;
//pass the add of the fst elem into regPC
}
// next_instruction_condition_check
int
do_next_instruction
(
struct
arm_state
*
state
,
struct
emu_analysis_struct
*
analysis
){
unsigned
int
ni
=
*
((
unsigned
int
*
)
state
->
regs
[
PC
]);
...
...
@@ -80,7 +91,7 @@ unsigned int val_reg_last12bits(unsigned int iw, struct emu_analysis_struct *ana
break
;
case
2
:
(
signed
)
val_in_rm
>>
amount
;
break
;
case
3
:
(
signed
)
val_in_rm
<<
amount
;
case
3
:
val_in_rm
>>
amount
||
((
val_in_rm
&
amount
)
<<
(
32
-
amount
));
// ??????????
break
;
default
:
exit
(
1
);
...
...
@@ -88,38 +99,257 @@ unsigned int val_reg_last12bits(unsigned int iw, struct emu_analysis_struct *ana
return
val_in_rm
;
}
// the carry out of shift op
unsigned
int
shift_carry_out
(
unsigned
int
iw
,
struct
emu_analysis_struct
*
analysis
){
unsigned
int
immediate
,
carry_out
,
val
,
amount
;
unsigned
int
sh_type
,
sh_op
;
immediate
=
(
iw
>>
25
)
&
0
b1
;
if
(
immediate
==
1
){
amount
=
(
iw
>>
8
)
&
0xF
;
val
=
(
iw
&
0xFF
);
carry_out
=
val
>>
amount
&
0
b1
;
}
else
{
val
=
analysis
->
regs_read
[
iw
&
0xF
];
sh_type
=
(
iw
>>
5
)
&
0
b11
;
sh_op
=
(
iw
>>
4
)
&
0
b1
;
if
(
sh_op
==
0
){
amount
=
(
iw
>>
7
)
&
0
b11111
;
}
else
{
amount
=
analysis
->
regs_write
[
iw
>>
8
&
0xF
];
}
if
(
sh_type
==
0
){
carry_out
=
val_in_rm
>>
(
32
-
amount
)
&
0
b1
;
}
else
{
carry_out
=
val_in_rm
>>
amount
&
0
b1
;
}
}
return
carry_out
;
}
void
and_instr
(
struct
arm_state
*
state
,
struct
emu_analysis_struct
*
analysis
,
unsigned
int
operand2
){
unsigned
int
s_bit
=
(
iw
>>
20
)
&
0
b1
;
unsigned
int
iw
=
*
((
unsigned
int
*
)
state
->
regs
[
PC
]);
unsigned
int
res
=
(
state
->
regs
[
rn
]
&
operand2
);
state
->
regs
[
rd
]
=
res
;
if
(
s_bit
==
1
){
state
->
c
=
shift_carry_out
(
iw
,
analysis
);
state
->
n
=
(
res
>>
31
)
&
0
b1
;
if
(
res
==
0
){
state
->
z
=
1
;
}
else
{
state
->
z
=
0
;
}
}
}
void
eor_instr
(
struct
arm_state
*
state
,
struct
emu_analysis_struct
*
analysis
,
unsigned
int
operand2
){
unsigned
int
s_bit
=
(
iw
>>
20
)
&
0
b1
;
unsigned
int
iw
=
*
((
unsigned
int
*
)
state
->
regs
[
PC
]);
unsigned
res
=
(
state
->
regs
[
rn
]
^
operand2
);
state
->
regs
[
rd
]
=
res
;
if
(
s_bit
==
1
){
state
->
c
=
shifte_carry_out
(
iw
,
analysis
);
state
->
n
=
(
res
>>
31
)
&
0
b1
;
if
(
res
==
0
){
state
->
z
=
1
;
}
else
{
state
->
z
=
0
;
}
}
}
void
sub_instr
(
struct
arm_state
*
state
,
struct
emu_analysis_struct
*
analysis
,
unsigned
int
operand2
){
unsigned
int
s_bit
=
(
iw
>>
20
)
&
0
b1
;
unsigned
int
iw
=
*
((
unsigned
int
*
)
state
->
regs
[
PC
]);
unsigned
res
=
(
state
->
regs
[
rn
]
-
operand2
);
state
->
regs
[
rd
]
=
res
;
if
(
s_bit
==
1
){
if
(
state
->
regs
[
rn
]
<
operand2
){
state
->
c
=
0
;
}
else
{
state
->
c
=
1
;
}
state
->
n
=
(
res
>>
31
)
&
0
b1
;
if
(
res
==
0
){
state
->
z
=
1
;
}
else
{
state
->
z
=
0
;
}
}
}
void
rsb_instr
(
struct
arm_state
*
state
,
struct
emu_analysis_struct
*
analysis
,
unsigned
int
operand2
){
unsigned
int
s_bit
=
(
iw
>>
20
)
&
0
b1
;
unsigned
int
iw
=
*
((
unsigned
int
*
)
state
->
regs
[
PC
]);
unsigned
res
=
operand2
-
state
->
regs
[
rn
]);
state
->
regs
[
rd
]
=
res
;
if
(
s_bit
==
1
){
if
(
operand2
<
state
->
regs
[
rn
]){
state
->
c
=
0
;
}
else
{
state
->
c
=
1
;
}
state
->
n
=
(
res
>>
31
)
&
0
b1
;
if
(
res
==
0
){
state
->
z
=
1
;
}
else
{
state
->
z
=
0
;
}
}
}
void
add_instr
(
struct
arm_state
*
state
,
struct
emu_analysis_struct
*
analysis
,
unsigned
int
operand2
){
unsigned
int
s_bit
=
(
iw
>>
20
)
&
0
b1
;
unsigned
int
iw
=
*
((
unsigned
int
*
)
state
->
regs
[
PC
]);
unsigned
res
=
operand2
+
state
->
regs
[
rn
]);
state
->
regs
[
rd
]
=
res
;
if
(
s_bit
==
1
){
if
(
res
<=
0xFFFFFFFF
){
state
->
c
=
0
;
}
else
{
state
->
c
=
1
;
}
state
->
n
=
(
res
>>
31
)
&
0
b1
;
if
(
res
==
0
){
state
->
z
=
1
;
}
else
{
state
->
z
=
0
;
}
}
}
void
tst_instr
(
struct
arm_state
*
state
,
struct
emu_analysis_struct
*
analysis
,
unsigned
int
operand2
){
unsigned
int
s_bit
=
(
iw
>>
20
)
&
0
b1
;
unsigned
int
iw
=
*
((
unsigned
int
*
)
state
->
regs
[
PC
]);
unsigned
res
=
operand2
+
state
->
regs
[
rn
]);
if
(
s_bit
==
1
){
if
(
res
<=
0xFFFFFFFF
){
state
->
c
=
0
;
}
else
{
state
->
c
=
1
;
}
state
->
n
=
(
res
>>
31
)
&
0
b1
;
if
(
res
==
0
){
state
->
z
=
1
;
}
else
{
state
->
z
=
0
;
}
}
}
void
teq_instr
(
struct
arm_state
*
state
,
struct
emu_analysis_struct
*
analysis
,
unsigned
int
operand2
){
unsigned
int
s_bit
=
(
iw
>>
20
)
&
0
b1
;
unsigned
int
iw
=
*
((
unsigned
int
*
)
state
->
regs
[
PC
]);
unsigned
res
=
(
state
->
regs
[
rn
]
^
operand2
);
if
(
s_bit
==
1
){
state
->
c
=
shifte_carry_out
(
iw
,
analysis
);
state
->
n
=
(
res
>>
31
)
&
0
b1
;
if
(
res
==
0
){
state
->
z
=
1
;
}
else
{
state
->
z
=
0
;
}
}
}
void
cmp_instr
(
struct
arm_state
*
state
,
struct
emu_analysis_struct
*
analysis
,
unsigned
int
operand2
){
unsigned
int
s_bit
=
(
iw
>>
20
)
&
0
b1
;
unsigned
int
iw
=
*
((
unsigned
int
*
)
state
->
regs
[
PC
]);
unsigned
res
=
(
state
->
regs
[
rn
]
-
operand2
);
if
(
s_bit
==
1
){
if
(
state
->
regs
[
rn
]
<
operand2
){
state
->
c
=
0
;
}
else
{
state
->
c
=
1
;
}
state
->
n
=
(
res
>>
31
)
&
0
b1
;
if
(
res
==
0
){
state
->
z
=
1
;
}
else
{
state
->
z
=
0
;
}
}
}
void
orr_instr
(
struct
arm_state
*
state
,
struct
emu_analysis_struct
*
analysis
,
unsigned
int
operand2
){
unsigned
int
s_bit
=
(
iw
>>
20
)
&
0
b1
;
unsigned
int
iw
=
*
((
unsigned
int
*
)
state
->
regs
[
PC
]);
unsigned
int
res
=
(
state
->
regs
[
rn
]
||
operand2
);
state
->
regs
[
rd
]
=
res
;
if
(
s_bit
==
1
){
state
->
c
=
shift_carry_out
(
iw
,
analysis
);
state
->
n
=
(
res
>>
31
)
&
0
b1
;
if
(
res
==
0
){
state
->
z
=
1
;
}
else
{
state
->
z
=
0
;
}
}
}
void
mov_instr
(
struct
arm_state
*
state
,
struct
emu_analysis_struct
*
analysis
,
unsigned
int
operand2
){
unsigned
int
s_bit
=
(
iw
>>
20
)
&
0
b1
;
unsigned
int
iw
=
*
((
unsigned
int
*
)
state
->
regs
[
PC
]);
state
->
regs
[
rd
]
=
operand2
;
if
(
s_bit
==
1
){
state
->
c
=
shift_carry_out
(
iw
,
analysis
);
state
->
n
=
(
res
>>
31
)
&
0
b1
;
if
(
res
==
0
){
state
->
z
=
1
;
}
else
{
state
->
z
=
0
;
}
}
}
void
data_processing_instr
(
struct
arm_state
*
state
,
struct
emu_analysis_struct
*
analysis
){
unsigned
int
operand2
,
immediate
,
iw
,
opCode
,
rd
,
rn
;
unsigned
int
operand2
,
immediate
,
iw
,
opCode
,
rd
,
rn
,
s_bit
,
amount
;
iw
=
*
((
unsigned
int
*
)
state
->
regs
[
PC
]);
immediate
=
(
iw
>>
25
)
&
0
b1
;
opCode
=
(
iw
>>
21
)
&
0xF
;
rd
=
(
iw
>>
12
)
&
0xF
;
rn
=
(
iw
>>
16
)
&
0xF
;
if
(
immediate
==
1
){
operand2
=
((
iw
&
0xFF
)
<<
0xF
)
||
(((
iw
>>
8
)
&
0xF
)
>>
0xFF
);
// ?????????
amount
=
(
iw
>>
8
)
&
0xF
;
operand2
=
(
iw
&
0xFF
);
// 32-bit
operand2
=
operand2
>>
(
amount
)
||
(
operand2
&
amount
)
<<
(
32
-
amount
);
}
else
{
operand2
=
val_reg_last12bits
(
iw
,
analysis
);
}
switch
(
opCode
)
{
case
0
:
state
->
regs
[
rd
]
=
(
state
->
regs
[
rn
]
&
operand2
)
;
case
0
:
and_instr
(
state
,
analysis
,
operand2
);
break
;
case
1
:
;
case
1
:
eor_instr
(
state
,
analysis
,
operand2
)
;
break
;
case
2
:
s
tate
->
regs
[
rd
]
=
state
->
regs
[
rn
]
=
operand2
;
case
2
:
s
ub_instr
(
state
,
analysis
,
operand2
)
;
break
;
case
3
:
;
case
3
:
rsb_instr
(
state
,
analysis
,
operand2
)
;
break
;
case
4
:
;
case
4
:
add_instr
(
state
,
analysis
,
operand2
)
;
break
;
case
8
:
;
case
8
:
tst_instr
(
state
,
analysis
,
operand2
)
;
break
;
case
9
:
;
case
9
:
teq_instr
(
state
,
analysis
,
operand2
)
;
break
;
case
10
:
;
case
10
:
cmp_instr
(
state
,
analysis
,
operand2
)
;
break
;
case
12
:
;
case
12
:
orr_instr
(
state
,
analysis
,
operand2
)
;
break
;
case
13
:
;
case
13
:
mov_instr
(
state
,
analysis
,
operand2
)
;
break
;
default
:
exit
(
1
);
...
...
@@ -154,7 +384,7 @@ void single_data_transfer_instr(struct arm_state *state, struct emu_analysis_str
if
(
p_index
==
1
){
analysis
->
regs_read
[
rn
]
=
state
->
regs
[
rn
];
if
(
up_bit
==
1
){
analysis
->
regs_read
[
rn
]
+=
offset
;
analysis
->
regs_read
[
rn
]
+=
offset
;
// ?????????????????
}
else
{
analysis
->
regs_read
[
rn
]
-=
offset
;
}
...
...
@@ -170,8 +400,57 @@ void single_data_transfer_instr(struct arm_state *state, struct emu_analysis_str
}
void
multiply_instr
(
struct
arm_state
*
state
,
struct
emu_analysis_struct
*
analysis
){
unsigned
iw
,
acc
,
set
,
rd
,
rn
,
rs
,
rm
,
res
;
iw
=
*
((
unsigned
int
*
)
state
->
regs
[
PC
]);
acc
=
(
iw
>>
21
)
&
0
b1
;
set
=
(
iw
>>
20
)
&
0
b1
;
rd
=
(
iw
>>
16
)
&
0xF
;
rn
=
(
iw
>>
12
)
&
0xF
;
rs
=
(
iw
>>
8
)
&
0xF
;
rm
=
iw
&
0xF
;
if
(
acc
==
1
){
state
->
regs
[
rd
]
=
state
->
regs
[
rm
]
*
state
->
regs
[
rs
]
+
state
->
regs
[
rn
];
}
else
{
state
->
regs
[
rd
]
=
state
->
regs
[
rm
]
*
state
->
regs
[
rs
];
}
res
=
state
->
regs
[
rd
];
if
(
set
==
1
){
state
->
n
=
(
res
>>
31
)
&
0
b1
;
if
(
res
==
0
){
state
->
z
=
1
;
}
else
{
state
->
z
=
0
;
}
}
}
//not sure about branch execution///////////////
void
branch_instr
(
struct
arm_state
*
state
,
struct
emu_analysis_struct
*
analysis
){
signed
int
offset
,
type
;
unsigned
int
iw
=
*
((
unsigned
int
*
)
state
->
regs
[
PC
]);
// shifted left 2 bits, sign extended to 32 bits??????????????
offset
=
((
signed
)
(
iw
&
0xFFFFFF
))
<<
2
;
state
->
regs
[
PC
]
+=
offset
;
}
//from sam's codes
int
*
readFile
(
char
*
filename
)
{
int
*
objectCode
=
calloc
(
16384
,
sizeof
(
int
));
//Creates a pointer with allocated space of 64KB
int
i
=
0
;
FILE
*
ptr
=
fopen
(
filename
,
"rb"
);
//Opens file "filename" to be read as a binary file
assert
(
ptr
!=
NULL
);
//Checks the file has been read
while
(
!
feof
(
ptr
))
{
fread
(
objectCode
+
i
,
4
,
1
,
ptr
);
//Stores the binary data in the files into the array objectCode
i
++
;
}
fclose
(
ptr
);
//Closes file "filename"
return
objectCode
;
// each elem in objectCode is an instr
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment