arm assembly代写-CSE30
时间:2022-03-11
CSE30 Practice Questions
Note: these problems are provided AS IS. You should assume that all the material
covered in the class is fair game for the exam (unless we tell you otherwise) and that the
material reflected in these problems is not necessarily an indication of the content of the
FINAL. We also attempted to make error free problems but make no guarantees that
these problems are indeed error free. There are also additional practice problems in the
midterm review discussion slides for practicing earlier content, and practice problems on Single
Cycle Design in the optional homework this week.
Table of Contents
1. Number Systems
2. C Pointers
3. C Memory Management
4. ARM Arithmetic/Control
5. ARM Data Transfer/Procedures/Stack Management
6. Digital Logic
7. ARM Assembly → Machine
Number Systems
1. Convert the following binary numbers into hexadecimal
a. 1111→ 0x__ f
b. 1100→ 0x__ c
c. 1010→ 0x__ a
d. 1110→ 0x__ e
e. 1101→ 0x__ d
f. 1011→ 0x__ b
2. What is the largest 2’s complement number that can be represented in 12 bits. What is
the smallest 2’s complement number that can be represented in 12 bits.
1 bit sign, 2^11 -1 = 2047
1000_0000 = -2048
NOTE: more practice in H&H 1.10, 1.11, 1.12
3. (H&H 1.25) Convert the following base-10 decimal numbers to unsigned binary numbers
a. 42
10_1010
b. 63
11_1111
c. 229
1110_0101
d. 845
11_0100_1101
4. Express -45 base-10 in binary (2’s complement, 8-bits)
0010_1101 -> 1101_0010 + 1 = 1101_0011
5. Convert the following decimal numbers to floating point in binary using IEEE-754 Single
Precision Format
sign (1) exponent (8) mantissa (23)
a. -0.1328125
1011_1110_0000_1000_0000_0000_0000_0000
b. 14.5
0100_0001_0110_1000_0000_0000_0000_0000
c. -13.375
1100_0001_0101_0110_0000_0000_0000_0000
d. 13.625
0100_0001_0101_1010_0000_0000_0000_0000
6. Convert the following floating point binary numbers to decimal
sign (1) exponent (8) mantissa (23)
a. 1011_1101_0000_0000_0000_0000_0000_0000
-0.03125
a. 1100_0000_0010_0011_0011_0011_0011_0011
-2.5499999523162841796875
b. 0100_0011_0000_1111_0000_0000_0000_0000
143
c. 1100_0001_1000_1110_0000_0000_0000_0000
-17.75
C Pointers
1. What are the values in arr after the following code executes?:
int val = 120;
int * ptr = &val;
int a = 12;
int ** pptr = &ptr;
val = a;
int arr[] = { 11, 2, 35, 469 };
*(arr + 2) = **pptr;
Solution: arr = {11, 2, 12, 469 }
2. What is the value of c after the following code executes?
char * str = “cse30fa19”;
char ** pptr = &str;
char c = *((*pptr) + 6);
Solution: c = ‘a’
3. What are the values of x, y, and z after the following code executes?
int arr[] = { 7, -11, 30, 104 };
int * p = arr;
int x = *p++;
int y = *(p++);
int z = *p - 3;
Solution: x=7 y=-11 z=27
4. What is the value of x after the following code executes?
int a[] = { 1, 0, 10 };
int b[] = { 2, 3, 6, 7 };
int * one = a;
int * two = b;
int ** three = &one;
int ** four = &two;
one = two;
int x = *(*three + 2);
Solution: x=6
5. Which char does a point do by the end of this code?
char * a = “kitten”;
char * b = a;
char ** c = &b;
*c = a + 2;
Solution: a points to ‘k’ (stores the address of the ‘k’)
6.
a. What will the following code print?
void swap( int a, int b){
a = a ^ b;
b = a ^ b;
a = a ^ b;
}
int x = 5;
int y = 100;
printf(“before swap x = %d y = %d\n”, x, y);
swap(x, y);
printf(“after swap x = %d y = %d\n”, x, y);
before swap x = 5 y = 100
after swap x = 5 y = 100
b. If this code needs to be fixed, modify it so that it performs the intended task.
We need to pass pointers to use pointers to allow the values of x and y to be
modified.
void swap( int *a, int *b){
*a = *a ^ *b;
*b = *a ^ *b;
*a = *a ^ *b;
}
int x = 5;
int y = 100;
printf(“before swap x = %d y = %d\n”, x, y);
swap(&x, &y);
printf(“after swap x = %d y = %d\n”, x, y);
7. Given the following arguments, what is printed when the following code executes?
(Answer A-E, where each code segmented is inserted into the main method shown
below.)
$ ./a.out almost done with CSE 30!
int main(int argc, char ** argv) {

return 0;
}
A) printf("%c", *argv[1]);
a
B) printf("%c", argv[3][0]);
w
C) printf("%c", argv[5][1]);
0
D) printf("%c", (*argv)[4]);
o
E) printf("%c", *argv[4]++);
C
C Memory Management
1. Say our goal is to allocate an array of 5 integers on the heap and assign them to be the
values 1-5 (e.g. arr[0] = 1, …. arr[4] = 5). What’s wrong with the following code?
int arr = malloc(sizeof(int) * 5);
for (int i = 0; i < sizeof(arr); i++) {
arr[i] += i + 1; // e.g. arr[3] += 4
}
Fixed code:
Option 1:
int arrayLen = 5;
int* arr = malloc(sizeof(int) * arrayLen);
for (int i = 0; i < arrayLen; i++) {
arr[i] = i + 1; // e.g. arr[3] = 4
}
Option 2:
int arrayLen = 5;
int* arr = calloc(arrayLen, sizeof(int)); // initialize to 0
for (int i = 0; i < arrayLen; i++) {
arr[i] += i + 1; // e.g. arr[3] += 4
}
2. Below, we have two char arrays and an int array. Say we want to iterate through them so
that each loop prints 1, 2, 3, 4, and 5 with new lines in between. Is there a problem with
any of the loops? If so, identify which one(s) and why.
int intArr[] = {1, 2, 3, 4, 5};
char charArr1[] = {‘1’, ‘2’, ‘3’, ‘4’, ‘5’};
char charArr2[] = “12345”;
// loop 1: int array
for (int i = 0; i < sizeof(intArr); i++) {
printf(“%d\n”, intArr[i]);
}
// loop 2: char array 1
for (int i = 0; i < sizeof(charArr1); i++) {
printf(“%d\n”, charArr1[i]);
}
// loop 3: char array 2
for (int i = 0; i < sizeof(charArr2); i++) {
printf(“%s\n”, charArr2[i]);
}
All 3 have different problems.
Fixed code:
int intArrLen = 5;
// can initialize the following with intArr[] instead, too
int intArr[intArrLen] = {1, 2, 3, 4, 5};
char charArr1[] = {‘1’, ‘2’, ‘3’, ‘4’, ‘5’};
// the following line is equivalent to:
// char charArr[] = {‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘\0’};
char charArr2[] = “12345”; //
// loop 1: int array
for (int i = 0; i < intArrLen; i++) {
printf(“%d\n”, intArr[i]);
}
// loop 2: char array 1
for (int i = 0; i < sizeof(charArr1); i++) {
printf(“%c\n”, charArr1[i]);
}
// loop 3: char array 2
// you could also use i < strlen(charArr2)
for (int i = 0; i < sizeof(charArr2) - 1; i++) {
printf(“%c\n”, charArr2[i]);
}
3. a) Fill in the following missing parts of code to run properly.
typedef struct Student student;
void setYearAndPid(student* s, int year, char* pid) {

}
struct Student {
int year;
char* pid;
}
int main() {
student* s = ;
setYearAndPid(s, 1, “A12345678”);
// imagine we did something useful with s
.
.
.

return 0;
}
typedef struct Student student;
void setYearAndPid(student* s, char* pid) {
s->year = year;
s->pid = malloc(strlen(pid) + 1);
strcpy(s->pid, pid);
}
struct Student {
int year;
char* pid;
}
int main() {
student* s = malloc(sizeof(student));
setYearAndPid(s, 1, “A12345678”);
// imagine we did something useful with s at some point
.
.
.
free(s->pid); // must free this before freeing s
free(s);
return 0;
}
b) Why don’t we need to malloc for s->year in setYearAndPid?
When we malloc’d for s, we malloc’d the size of one student, which is the sum
of the sizes of its contents (plus some padding, outside scope of the course). This
means we allocated space for an int and a pointer. So, we already have space
allocated on the heap for the int, we just need to initialize it. The pointer, likewise,
already had space allocated for it and needed to be initialized, but we also needed to
allocate additional space for the chars in the string pointed to by pid.
4. Say we allocated an array on heap, assigned a pointer to its first element, did some stuff,
and then wanted to deallocate the memory. What’s wrong with the code below?
int* arr = malloc(sizeof(int) * 5);
for (int i = 0; i < 5; i++) {
arr[i] = i;
}
int* arrPtr = arr;
// did some useful stuff with arr and arrPtr
.
.
.
free(arrPtr);
free(arr);
We are double freeing the same block of memory on the heap.
5. a) Say we had the Student struct from Q3 and wanted to allocate an array of 3
students onto the heap. For simplicity, we’ll say student 1’s year is 1 and PID is A1,
student 2’s year is 2 and PID is A2, and student 3’s year is 3 and PID is A3. Implement
parts of a main that allocate these 3 students on the heap in an array and assign their
years and PIDs using the setYearAndPid function from Q3 (don’t worry about freeing
yet).
int main() {
student** studentArr = malloc(sizeof(student*) * 3);
// student 1
studentArr[0] = malloc(sizeof(student));
setYearAndPid(studentArr[0], 1, “A1”);
// student 2
studentArr[1] = malloc(sizeof(student));
setYearAndPid(studentArr[1], 2, “A2”);
// student 3
studentArr[2] = malloc(sizeof(student));
setYearAndPid(studentArr[2], 3, “A3”);
}
b) Add the code necessary to free everything before exiting main.
int main() {
.
.
// imagine the code from part A is up here,
// plus other things we did with the data
.
.
for (int i = 0; i < 3; i++) {
free(studentArr[i]->pid); // free malloc’d pids
free(studentArr[i]); // free malloc’d students
}
free(studentArr); // free malloc’d array of student
pointers
}
c) (Pointer & Memory Practice) Write a function that takes in an array of student pointers
to students (like studentArr in part B and sorts the students in place by seniority
(highest year). Any sorting algorithm is fine. In part B, we knew the students’ years for
the sake of the example, but in practice, a function won’t know its inputs and needs to be
general. If, however, the input array were the one from B, then it should order student 3
at index 0, student 2 at index 1, and student 1 at index 2.
void sortStudentsBySeniority(student** students, int
numberOfStudents) {
// fill in
}
// this uses selection sort as an example
// assumes numberOfStudents is the correct length for the array
void sortStudentsBySeniority(student** students, int
numberOfStudents) {
student* temp;
int maxIndex;
for(int i = 0; i < numberOfStudents - 1; i++) {
maxIndex = i;
for(int j = i + 1; j < numberOfStudents; j++) {
if (students[j]->year > students[maxIndex]->year) {
maxIndex = j;
}
}
temp = students[i];
students[i] = students[maxIndex];
students[maxIndex] = temp;
}
}
6. Do the following pieces of code cause a dangling pointer, memory leak, neither, or both?
a)
int** myFunction() {
int** i = malloc(sizeof(int*) * 10);
return i;
}
int main() {
int** i = myFunction();
free(i);
i = NULL;
return 0;
}
Neither
b)
int** myFunction() {
int* i = malloc(sizeof(int) * 10);
return &i;
}
int main() {
int** i = myFunction();
i = NULL;
return 0;
}
By the end of the program, only a memory leak. Right when we return from myFunction, i
is a dangling pointer. This is because main’s i will store a value that has gone out of
scope on the stack (myFunction’s i is out of scope when we get back to main, so
main’s i stores the address of an out-of-scope variable). But then when we set i to
NULL, it makes it non-dangling. So by the end of the program, we don’t have a dangling
pointer, but main’s i initially is one that is dangling. We have a memory leak because we
never free the array of 10 ints anywhere.
So the answer is that by the end of the program, we only have a memory leak, but it’s
important to realize that main’s i was initially a dangling pointer when we returned from
myFunction. It would not have been safe to use it for anything before setting it to NULL
because it was pointing to out-of-scope memory.
Poorly-framed question on our part. The most important part of this is to know that
main’s i is initially a dangling pointer before being set to NULL
c)
int* myFunction() {
int i[] = {1, 2, 3, 4};
return i;
}
int main() {
int* i = myFunction();
return 0;
}
Dangling pointer. main’s i will store a value that has gone out of scope on the stack
(myFunction’s i is out of scope when we get back to main, so main’s i stores the
address of an out-of-scope variable).
d)
int* myFunction() {
int* i = malloc(sizeof(int));
return i;
}
int main() {
int* i = myFunction();
free(i);
return 0;
}
Dangling pointer. After we free main’s i, it still stores the same address it did before
being freed, but now that memory is invalid. And because that space has been freed, it
means that it can be used to store other heap allocated variables in the future. What if
we allocated something else and it decided to use this memory address to store it? Now
i will store the address of a different variable’s data, when it shouldn’t.
Note: A quick way to check for potential memory leaks and double freeing is checking if you
called free as many times as you called malloc / calloc. If you called free more times
than malloc / calloc, you probably double freed something (or freed something else you
weren’t supposed to). If you called free less times than malloc / calloc, you have a
memory leak. If they’re equal, there is a higher chance that you don’t have memory leaks, but
you can’t assume no issues purely from the counts. You can, however, definitively say that you
have a memory issue when the counts are unequal.
ARM Arithmetic/Control
1. Translate the following C function into assembly (remember to include the prolog and
epilog):
int fun_func( int * src, int val ) {
int i;
for( i = 10; i > 0; i--) {
if( i > 5 ) {
val = val + 5;
} else if( i == 5 ) {
val = val * val;
} else {
val = val - 10;
}
}
return val;
}
Solution:
(6/7/21 - WARNING: this is a bad example because we should be saving the r0-r3 in the
parameter save area). Also we don’t have to save r0-r3 because these are not callee
saved.)
// r0 - int * src
// r1 - int val
// r2 - i
fun_func:
push {r2, fp} // prolog - save registers
add fp, sp, #4 // adjust fp
mov r2, #10 // int i = 10
loop: cmp r2, #0 // for(int i = 10, i > 0, i--)
ble end_loop // .
cmp r2, #5 // if( i > 5)
ble one // .
add r1, r1, #5 // val = val + 5
b end_if
one:
cmp r2, #5 // else if( i == 5)
bne two: // .
mul r1, r1, r1 // val = val * val
b end_if
two: // else
sub r1, r1, #10 // val = val - 10
end_if:
sub r2, r2, #1 // i--
b loop
end_loop:
mov r0, r1
sub sp, fp, #4 // epilog
pop {r2, fp}
bx lr // return val
2. Translate the following C function into assembly (remember to include the prologue and
epilogue):
int mystery_func( int a ) {
if( a > 10 ) {
return 1;
}
return mystery_func( a + 2 )
+ mystery func( a - 3) ;
}
Solution:
// r0 - int a
// r1 - a+2
// r2 - a-3
// r3 - return of mystery_func(r1)
// r4 - return of mystery-func(r2)
mystery_func:
push {r1-r4, fp, lr} // prologue
add fp, sp, #20
cmp r0, #10 // if( a > 10 )
ble one // .
mov r0, #1 // r0 = 1
b end
one:
add r1, r0, #2 // r1 = a + 2
sub r2, r0, #3 // r2 = a - 3
mov r0, r1 // r0 = mystery_func(r1)
bl mystery_func // .
mov r3, r0 // r3 = r0
mov r0, r2 // r0 = mystery_func(r2)
bl mystery_func // .
mov r4, r0 // r4 = r0
add r0, r3, r4 // r0 = r3 + r4
end: sub sp, fp, #20 // epilogue
pop {r1-r4, fp, lr}
bx lr
3. Annotate the following ARM code with pseudo code that describes its function (assume
r0 is a parameter called x).
mov r4, #0 // i = 0;
1: cmp r4, 100 //
beq done //
add r0, r0, r4 //
add r4, r4, #1 //
b 1b //
done: mvn r0 //
mov r4, #0 // i = 0;
1: cmp r4, 100 // for (i=0; i<100; i++) {
beq done // .
add r0, r0, r4 // x = x + i
add r4, r4, #1 // .
b 1b // }
done: mvn r0, r0 // return (~x)
4. Write an ARM function sum_func, that takes in a pointer to the start of an array of ints
as r0 and a pointer to the last cell in the array of ints as r1, and calculates the sum of
all ints in the array. Assume non-degenerate input.
Solution:
// r0 - startPtr
// r1 - endPtr
// r2 - sum
// r3 - value from array
sum_func: push {r2-r3, fp} // prolog
add fp, sp, #8
mov r2, #0 // r2 = 0
add r1, r1, #4 // r1 = r1 + 4
b loop: cmp r0, r1 // while r0 != r1
beq end // .
ldr r3, [r0] // r3 = *r0
add r2, r2, r3 // r2 += r3
add r0, r0, #4 // r0++
b loop
end: mov r0, r2
sub sp, fp, #8
pop {r2-r3, fp}
bx lr
5. Write an ARM function that calculates the Fibonacci numbers iteratively. Do not use
recursion. Assume non-degenerate input. fib(0) = 1, fib(1) = 1, fib(2) = 2, fib(3) = 3, …
Solution:
// r0 - fib number to calculate
// r1, r2 - prev two fib numbers
// r3 - sum of prev two fib numbers
fib: push {r1-r3, fp}
add fp, sp, #12
cmp r0, #0 // if(r0 == 0)
bne one // .
mov r0, #1 // r0 = 1
b end
one: cmp r0, #1 // if(r0 == 1)
bne two // .
mov r0, #1 // r0 = 1
b end
two: mov r1, #1 // r1 = 1
mov r2, #1 // r2 = 1
sub r0, r0, #1 // r0 = r0 - 1
loop: cmp r0, #0 // while(r0 > 0)
ble three // .
add r3, r1, r2 // r3 = r1 + r2
mov r1, r2 // r1 = r2
mov r2, r3 // r2 = r3
sub r0, r0, #1 // r0 = r0 - 1
b loop
three: mov r0, r3 // r0 = r3
end: sub sp, fp, #12 // epilog
pop {r1-r3, fp}
bx lr
ARM Data Transfer/Procedures/Stack Management
1. Given the following code, what is the value printed
.global fn
fn: push {lr}
cmp r1, #1
beq done
add r0, r0, r1
sub r1, r1, #1
bl fn
done:
pop {lr}
bx lr
int main(){
int x;
x = fn(0, 5);
printf(“%d\n”, x);
}
fn: push {lr}
cmp r1, #1 // if (r1 != 1) {
beq done // .
add r0, r0, r1 // r0 = r0 + r1
sub r1, r1, #1 // r1 = r1 - 1
bl fn // f(r0, r1)
done: // }
pop {lr}
bx lr
int main(){
int x;
x = fn(0, 5);
printf(“%d\n”, x);
}
fn(0,5)-> r0 = 0 + 5 ; fn(5, 4) -> r0 = 5 + 4; fn(9, 3); r0 = 9
+ 3; f(12, 2)-> r0 = 12+2; f(14, 1)
14
2. Fill in the appropriate values for FP_OFFSET, A_OFFSET, B_OFFSET, X_OFFSET,
LOCAL_SPACE, PARAM_SPACE
Function Prototype
int tatooine (int x){
int a;
int b;
a = x + 4;
b = x - 4;
dofunc(&a, &b);
return ~x;
}
Fill in values below
.global tatooine
.align 4
.equ NUL, 0
.equ FP_OFFSET,_________ 20 // (6-1) * 4
.equ LOCAL_SPACE, _______ 8 // 2 (A, B) * 4
.equ PARAM_SPACE, _______ 4 // 1 (X) * 4
.equ A_OFFSET, _______ -24 // (fp - 20 end of
save area) - 4
.equ B_OFFSET, _______ -28 //
.equ X_OFFSET, _______ -32
tatooine:
push {r4-r7, fp, lr} // prolog
add fp, sp, #FP_OFFSET // . set fp
sub sp, sp, #LOCAL_SPACE // . sp <- bot of
local
sub sp, sp, #PARAM_SPACE // . sp <- bot of
save param
mov r4, r0 // a = x + 4
add r4, r4, #4 // .
str r4, [fp, #A_OFFSET] // .
mov r4, r0 // b = x - 4
sub r4, r4, #4 // .
str r4, [fp, #B_OFFSET] // .
str r0, [fp, #X_OFFSET] // save x
add r0, fp, #A_OFFSET // r0 = &a
add r1, rp, #B_OFFSET // r1 = &b
bl dofunc // dofunc(&a, &b)
ldr r0, [fp, #X_OFFSET] // restore x
mvn r0, r0
sub sp, fp, #FP_OFFSET // epilog
pop {r4-r7, fp, lr}
bx lr
3. When does a function need to push and pop a preserved register to and from the stack?
If it modifies its value. A function must preserve it’s caller’s preserved register values so
that when it returns to its caller, the registers are just as they were before the function
was called.
4. When might a function push and pop a non-preserved register to and from the stack?
If it’s storing a local variable within a non-preserved register, but wants to call another
function. Since it can’t count on the second function to not modify the non-preserved
register (by convention), it will need to store it on the stack before calling the other
function.
5. If you push r5 to the stack, what are the two equivalent instructions being performed, and
what register value(s) are you updating?
add sp, #-4
str r5, [sp]
sp (r13), pc (r15)
6. When you pop r7 from the stack, what are the two equivalent instructions being
performed, and what register value(s) are you updating?
ldr r7, [sp]
add sp, #4
r7, sp (r13), pc (r15)
7. When you branch using b, what register value(s) are you updating?
pc (r15)
8. When you branch using bl, what register value(s) are you updating?
pc (r15)
lr (r14)
9. When you use bx lr, what register value(s) are you updating?
pc (r15)
10. Which of the following instructions involve accesses to memory (RAM): add, sub, mov,
ldr, str, bl, bx, push, pop?
ldr, str, push, pop
11. Why do we want to minimize accesses to memory (RAM)?
It takes much longer to go out to memory to store or load a value than it does to operate
directly on the processor
12. True or False: When we pop values from the stack, that memory on the stack is zero’d
out / cleared
False. This means that when you return from a function, anything that was on the
previous function’s stack frame is still there (unless the function manually zero’d out the
memory) until overwritten by new pushes/stores to the stack
13. What is wrong with the following (assume the stack pointer isn’t being modified by
anything outside of what is shown)?
myFunc: push {r4, r5, fp}
add fp, sp, #8
.
. // assume we modify r4 and r5 here
.
push r1
.
.
.
sub sp, fp, #8
pop {r4, r5, fp}
bx lr
We modified fp, so we need to make sure we push it. Because we push it, that changes
the offset for setting the frame pointer to 8. In addition, because we pushed a local
variable (r1), if we never popped r1, then sp points to where r1 was pushed to. Therfore,
when we go to pop {r4, r5, fp}, sp is at the wrong place to pop because it’s pointing at
where r1 was pushed. That pop would pop the local variable from r1 into r4, r4 into r5,
and r5 into fp. We need to add the sub statement to set sp to be the bottom/end of the
pushed preserved register values before popping to restore them. We also need to pop
fp since we pushed it.
14. What is wrong with the following (assume the stack pointer isn’t being modified by
anything outside of what is shown)?
myFunc: push r4
push r5
.
. // assume we modify r4 and r5 here
.
pop r5
pop r4
bx lr
We pushed r4 and then r5, so we need to pop in reverse order. The original would pop
the previous r5 value into r4 and the previous r4 into r5. When we do something like
push {r4, r5} and pop {r4, r5}, this ordering is handled for us.
Digital Logic
1. Produce a truth table for the output F from the logic below:
F = ~(AB) + (B~C)
A B C F
0 0 0 1
0 0 1 1
0 1 0 1
0 1 1 1
1 0 0 1
1 0 1 1
1 1 0 1
1 1 1 0
2. a) Fill in the truth table for the following circuit diagram
A B C F
1 1 1 1
1 1 0 1
1 0 1 1
1 0 0 0
0 1 1 0
0 1 0 0
0 0 1 1
0 0 0 0
b) Write the boolean expression that this circuit represents
F = AB + ~BC
3. Suppose the carry-in to the ALU described in class is stuck at 1. Which operations
(among ADD, SUB, OR, and AND) would no longer function properly?
Just ADD.
4. What is the input state of the SR-Latch from class that produced an inconsistent output?
11.
5. How did the D-latch in class get around this issue?
In two ways. First, it added a write-enable input that is ANDed with the former inputs S
and R (we hooked it up to the clock). That way when write-enable is 0, you retain the
state Q. Second, we had a single input D whose value is sent to S and NOT D is sent to
R. Hence there can be no input that produces a 1 for both S and R.
6. Other ideas: Take a circuit and produce a corresponding truth table. Given a function,
apply boolean algebra to simplify. Describe how to build a D flip-flop with a two D
latches as we did in class.
ARM Assembly → Machine
1. Convert the following ARM instructions to machine code. Display your answer in HEX.
ADD r4, r5, r6
Fields: 1110 00 0 0100 0 0101 0100 00000 00 0 0110
1110 0000 1000 0101 0100 0000 0000 0110 => 0xe0854006
LDR r8, [r13, #8]
L = 1, B = 0, I = 0, P =1, W = 0 U = 1
Fields: 1110 01 0 1 1 0 0 1 1101 1000 0000 0000 1000
1110 0101 1001 1101 1000 0000 0000 1000 => 0xe59d8008
2. Convert the following machine instructions (in hex) into ARM assembly.
0xe503403c
Fields: 1110 01 0 1 0 0 0 0 0011 0100 0000 0011 1100
I = 0, P =1, U = 0, B = 0, W = 0, L = 0
STR R4, [R3, #-60]
0xe382100f
ORR R1, R2, #15

essay、essay代写