Floating point variable's value missing in data memory - c

I am a master student and currently doing my summer final project, which is about design a MIPS processor with a FPU and implement in a FPGA.
The instructions that I'm going to implement are depended on the cross-compiler I'm using. So, from a hardware designer point of view, I started the project by first looking the instructions can be generated from the compiler.
For integer design(the main core design), I wrote some C codes, here for example, a simple one:
int main ()
{
int a,b,c;
a=1;
b=2;
c=a+2;
}
A simple addition, the compiler gives assembly codes: (I just posted the assembly codes in main, because I did not plan to run a operating system on my MIPS)
00400168 <main>:
400168: 27bdffe8 addiu sp,sp,-24
40016c: afbe0010 sw s8,16(sp)
400170: 03a0f021 move s8,sp
400174: 24020001 li v0,1
400178: afc20008 sw v0,8(s8)
40017c: 24020002 li v0,2
400180: afc20004 sw v0,4(s8)
400184: 8fc20008 lw v0,8(s8)
400188: 00000000 nop
40018c: 20420002 addi v0,v0,2
400190: afc20000 sw v0,0(s8)
400194: 03c0e821 move sp,s8
400198: 8fbe0010 lw s8,16(sp)
40019c: 27bd0018 addiu sp,sp,24
4001a0: 03e00008 jr ra
I like to understand the assembly code, that can helps me more understand MIPS architecture, and based on the instructions order I can design a hazard detection unit based on the compiler.
We can see from those 4 instruction:
400174: 24020001 li v0,1
400178: afc20008 sw v0,8(s8)
40017c: 24020002 li v0,2
400180: afc20004 sw v0,4(s8)
The compiler loads 1, 2 into variable a, b.
For the integer assembly code, I can understand no problems.
Ok, lets go to the floating point unit, as the same, I wrote a very similar C :
Floating point testing C code
void main ()
{
float a,b,c;
a=1;
b=2;
c=a+b;
}
Now the assembly codes are much different:
00400168 <main>:
400168: 27bdffe8 addiu sp,sp,-24
40016c: afbe0010 sw s8,16(sp)
400170: 03a0f021 move s8,sp
400174: c7808004 lwc1 $f0,-32764(gp)
400178: 00000000 nop
40017c: e7c00008 swc1 $f0,8(s8)
400180: c7808008 lwc1 $f0,-32760(gp)
400184: 00000000 nop
400188: e7c00004 swc1 $f0,4(s8)
40018c: c7c20008 lwc1 $f2,8(s8)
400190: c7c00004 lwc1 $f0,4(s8)
400194: 00000000 nop
400198: 46001000 add.s $f0,$f2,$f0
40019c: e7c00000 swc1 $f0,0(s8)
4001a0: 03c0e821 move sp,s8
4001a4: 8fbe0010 lw s8,16(sp)
4001a8: 27bd0018 addiu sp,sp,24
4001ac: 03e00008 jr ra
4001b0: 00000000 nop
Doesn't like pervious code, those 6 instructions looks like the program load the variable's value from data memory instead using instruction li:
400174: c7808004 lwc1 $f0,-32764(gp)
400178: 00000000 nop
40017c: e7c00008 swc1 $f0,8(s8)
400180: c7808008 lwc1 $f0,-32760(gp)
400184: 00000000 nop
400188: e7c00004 swc1 $f0,4(s8)
Here comes the problem, I just can not figure out what is value stored in -32764(gp) and f0,-32760(gp), because there are not any SW instructions that try to store data into those address.
Here is the fully assembly code generated by compiler:
floatadd: file format elf32-bigmips
Disassembly of section .init:
00400018 <_init>:
400018: 27bdffe0 addiu sp,sp,-32
40001c: afbf0014 sw ra,20(sp)
400020: 0c10003a jal 4000e8 <frame_dummy>
400024: 00000000 nop
400028: 0c10006d jal 4001b4 <__do_global_ctors_aux>
40002c: 00000000 nop
400030: 8fbf0014 lw ra,20(sp)
400034: 27bd0020 addiu sp,sp,32
400038: 03e00008 jr ra
40003c: 00000000 nop
Disassembly of section .text:
00400040 <_ftext>:
400040: 27bdffe0 addiu sp,sp,-32
400044: afb10014 sw s1,20(sp)
400048: 3c110040 lui s1,0x40
40004c: 9222126c lbu v0,4716(s1)
400050: afbf0018 sw ra,24(sp)
400054: 14400019 bnez v0,4000bc <_ftext+0x7c>
400058: afb00010 sw s0,16(sp)
40005c: 3c100040 lui s0,0x40
400060: 8e021260 lw v0,4704(s0)
400064: 00000000 nop
400068: 8c430000 lw v1,0(v0)
40006c: 00000000 nop
400070: 10600009 beqz v1,400098 <_ftext+0x58>
400074: 24420004 addiu v0,v0,4
400078: 0060f809 jalr v1
40007c: ae021260 sw v0,4704(s0)
400080: 8e021260 lw v0,4704(s0)
400084: 00000000 nop
400088: 8c430000 lw v1,0(v0)
40008c: 00000000 nop
400090: 1460fff9 bnez v1,400078 <_ftext+0x38>
400094: 24420004 addiu v0,v0,4
400098: 3c020000 lui v0,0x0
40009c: 24420000 addiu v0,v0,0
4000a0: 10400005 beqz v0,4000b8 <_ftext+0x78>
4000a4: 24020001 li v0,1
4000a8: 3c040040 lui a0,0x40
4000ac: 0c000000 jal 0 <_init-0x400018>
4000b0: 24840244 addiu a0,a0,580
4000b4: 24020001 li v0,1
4000b8: a222126c sb v0,4716(s1)
4000bc: 8fbf0018 lw ra,24(sp)
4000c0: 8fb10014 lw s1,20(sp)
4000c4: 8fb00010 lw s0,16(sp)
4000c8: 03e00008 jr ra
4000cc: 27bd0020 addiu sp,sp,32
004000d0 <call___do_global_dtors_aux>:
4000d0: 27bdffe8 addiu sp,sp,-24
4000d4: afbf0010 sw ra,16(sp)
4000d8: 8fbf0010 lw ra,16(sp)
4000dc: 00000000 nop
4000e0: 03e00008 jr ra
4000e4: 27bd0018 addiu sp,sp,24
004000e8 <frame_dummy>:
4000e8: 3c020000 lui v0,0x0
4000ec: 27bdffe8 addiu sp,sp,-24
4000f0: 3c040040 lui a0,0x40
4000f4: 3c050040 lui a1,0x40
4000f8: 24420000 addiu v0,v0,0
4000fc: afbf0010 sw ra,16(sp)
400100: 24840244 addiu a0,a0,580
400104: 10400003 beqz v0,400114 <frame_dummy+0x2c>
400108: 24a51270 addiu a1,a1,4720
40010c: 0c000000 jal 0 <_init-0x400018>
400110: 00000000 nop
400114: 3c040040 lui a0,0x40
400118: 8c831258 lw v1,4696(a0)
40011c: 3c020000 lui v0,0x0
400120: 10600007 beqz v1,400140 <frame_dummy+0x58>
400124: 24590000 addiu t9,v0,0
400128: 24841258 addiu a0,a0,4696
40012c: 13200004 beqz t9,400140 <frame_dummy+0x58>
400130: 00000000 nop
400134: 8fbf0010 lw ra,16(sp)
400138: 03200008 jr t9
40013c: 27bd0018 addiu sp,sp,24
400140: 8fbf0010 lw ra,16(sp)
400144: 00000000 nop
400148: 03e00008 jr ra
40014c: 27bd0018 addiu sp,sp,24
00400150 <call_frame_dummy>:
400150: 27bdffe8 addiu sp,sp,-24
400154: afbf0010 sw ra,16(sp)
400158: 8fbf0010 lw ra,16(sp)
40015c: 00000000 nop
400160: 03e00008 jr ra
400164: 27bd0018 addiu sp,sp,24
00400168 <main>:
400168: 27bdffe8 addiu sp,sp,-24
40016c: afbe0010 sw s8,16(sp)
400170: 03a0f021 move s8,sp
400174: c7808004 lwc1 $f0,-32764(gp)
400178: 00000000 nop
40017c: e7c00008 swc1 $f0,8(s8)
400180: c7808008 lwc1 $f0,-32760(gp)
400184: 00000000 nop
400188: e7c00004 swc1 $f0,4(s8)
40018c: c7c20008 lwc1 $f2,8(s8)
400190: c7c00004 lwc1 $f0,4(s8)
400194: 00000000 nop
400198: 46001000 add.s $f0,$f2,$f0
40019c: e7c00000 swc1 $f0,0(s8)
4001a0: 03c0e821 move sp,s8
4001a4: 8fbe0010 lw s8,16(sp)
4001a8: 27bd0018 addiu sp,sp,24
4001ac: 03e00008 jr ra
4001b0: 00000000 nop
004001b4 <__do_global_ctors_aux>:
4001b4: 3c020040 lui v0,0x40
4001b8: 2442124c addiu v0,v0,4684
4001bc: 8c44fffc lw a0,-4(v0)
4001c0: 27bdffe0 addiu sp,sp,-32
4001c4: 2403ffff li v1,-1
4001c8: afb00010 sw s0,16(sp)
4001cc: afbf0018 sw ra,24(sp)
4001d0: afb10014 sw s1,20(sp)
4001d4: 10830008 beq a0,v1,4001f8 <__do_global_ctors_aux+0x44>
4001d8: 2450fffc addiu s0,v0,-4
4001dc: 2411ffff li s1,-1
4001e0: 0080f809 jalr a0
4001e4: 2610fffc addiu s0,s0,-4
4001e8: 8e040000 lw a0,0(s0)
4001ec: 00000000 nop
4001f0: 1491fffb bne a0,s1,4001e0 <__do_global_ctors_aux+0x2c>
4001f4: 00000000 nop
4001f8: 8fbf0018 lw ra,24(sp)
4001fc: 8fb10014 lw s1,20(sp)
400200: 8fb00010 lw s0,16(sp)
400204: 03e00008 jr ra
400208: 27bd0020 addiu sp,sp,32
0040020c <call___do_global_ctors_aux>:
40020c: 27bdffe8 addiu sp,sp,-24
400210: afbf0010 sw ra,16(sp)
400214: 8fbf0010 lw ra,16(sp)
400218: 00000000 nop
40021c: 03e00008 jr ra
400220: 27bd0018 addiu sp,sp,24
Disassembly of section .fini:
00400224 <_fini>:
400224: 27bdffe0 addiu sp,sp,-32
400228: afbf0014 sw ra,20(sp)
40022c: 0c100010 jal 400040 <_ftext>
400230: 00000000 nop
400234: 8fbf0014 lw ra,20(sp)
400238: 27bd0020 addiu sp,sp,32
40023c: 03e00008 jr ra
400240: 00000000 nop
I am not good at MIPS assembly, can someone explain where are the floating point variable' value 1 and 2?

About your question
ELF executables can have one or more sections filled with the static data (string, floating point numbers, numbers, whatever) used by the program.
This sections are loaded into memory by the loader with the rest of the program, thereby avoiding intermixing code and data and reducing the code size.
For the ELF on MIPS systems you should refer to this where there is this nice picture:
As you can see $gp is used to address the section .sdata and .sbss, where the initial s stands for small.
All these efforts are taken to minimize code size as by using $gp the compiler can generate 16 bit offsets (versus the 32 bit ones normally used).
Since the offset is signed, $gp is placed in the middle of a (at most) 64 KiB region formed by .sdata + .sbss.
Your floating points value are not coded directly in the instructions because FP instruction does not takes immediates, instead they are saved into a readonly section and loaded from there.
About your purpose
Why in the end do you care about this?
If your goal is to design an implementation of the MIPS ISA, just pick the specific ISA (MIPS32 I? MIPS32 IV? MIPS 64?), get the documents, get the whole picture and implement a microarchitecture for it.
If an instruction is a valid instruction according to your chosen ISA then your implementation must be able to execute it, don't worry about what the compilers are doing, they are grown up, they can take care of them selves and in the end if the code you are executing is broken, who cares? As long it is valid.
These will help you:
MIPS32™ Architecture For Programmers Volume I: Introduction to the MIPS32™ Architecture
MIPS32™ Architecture For Programmers Volume II: The MIPS32™ Instruction Set

Related

can you produce BEQL MIPS instruction with C code?

So I have this code snippet in C
int unit_test_case08(int a, int b)
{
int success = 1336;
if(a != b)
{
success = 1337;
}
else
{
success = -1;
}
return success;
}
Which translates in MIPS to
unit_test_case08:
addiu $sp,$sp,-24
sw $fp,20($sp)
move $fp,$sp
sw $4,24($fp)
sw $5,28($fp)
sw $6,32($fp)
li $2,1336 # 0x538
sw $2,8($fp)
lw $3,24($fp)
lw $2,28($fp)
nop
beq $3,$2,$L2
nop
li $2,1337 # 0x539
sw $2,8($fp)
b $L3
nop
$L2:
li $2,-1 # 0xffffffffffffffff
sw $2,8($fp)
$L3:
lw $2,8($fp)
move $sp,$fp
lw $fp,20($sp)
addiu $sp,$sp,24
jr $31
nop
But for my question, im trying to create some test cases for my emulator, but am finding it hard to generate some code in C that will get me BEQL instead of BEQ?
beq $3,$2,$L2
This question extends to most of the "Likelys" if possible.
I am a very new to MIPS.
I would like to learn how to code a test case in C that would translate to BEQL instead of BEQ.

Converting MIPS assembly to C

I am working on converting MIPS to C, and I've been stuck on this for several days.
I've started with manually converting MIPS to C, and even though I've been working on it for several days, my resulting program in C still doesn't run as needed, and I feel like there is a small mistake that I overlooked, and I would really appreciate your help.
I started conversion with toplevel_fnc, and then with subroutine_fnc.
Here is a part of the MIPS code.
Subroutine:
build/program-mips: file format elf32-tradbigmips
Disassembly of section my_text:
00404ed0 <subroutine_fnc>:
404ed0: 27bdffd8 addiu sp,sp,-40
404ed4: afbe0024 sw s8,36(sp)
404ed8: 03a0f025 move s8,sp
404edc: afc40028 sw a0,40(s8)
404ee0: 8fc40028 lw a0,40(s8)
404ee4: 27c20018 addiu v0,s8,24
404ee8: 00402825 move a1,v0
404eec: 24060001 li a2,1
404ef0: 24020fa3 li v0,4003
404ef4: 0000000c syscall
404ef8: afc70008 sw a3,8(s8)
404efc: afc2000c sw v0,12(s8)
404f00: 8fc20008 lw v0,8(s8)
404f04: 00000000 nop
404f08: 14400004 bnez v0,404f1c <subroutine_fnc+0x4c>
404f0c: 00000000 nop
404f10: 8fc2000c lw v0,12(s8)
404f14: 10000002 b 404f20 <subroutine_fnc+0x50>
404f18: 00000000 nop
404f1c: 2402ffff li v0,-1
404f20: afc20010 sw v0,16(s8)
404f24: 8fc20010 lw v0,16(s8)
404f28: 00000000 nop
404f2c: 04410006 bgez v0,404f48 <subroutine_fnc+0x78>
404f30: 00000000 nop
404f34: 24040001 li a0,1
404f38: 24020fa1 li v0,4001
404f3c: 0000000c syscall
404f40: afc70008 sw a3,8(s8)
404f44: afc20014 sw v0,20(s8)
404f48: 8fc20010 lw v0,16(s8)
404f4c: 00000000 nop
404f50: 14400004 bnez v0,404f64 <subroutine_fnc+0x94>
404f54: 00000000 nop
404f58: 00001025 move v0,zero
404f5c: 10000002 b 404f68 <subroutine_fnc+0x98>
404f60: 00000000 nop
404f64: 83c20018 lb v0,24(s8)
404f68: 03c0e825 move sp,s8
404f6c: 8fbe0024 lw s8,36(sp)
404f70: 27bd0028 addiu sp,sp,40
404f74: 03e00008 jr ra
404f78: 00000000 nop
and toplevel:
00404f7c <toplevel_fnc>:
404f7c: 27bdffc0 addiu sp,sp,-64
404f80: afbf003c sw ra,60(sp)
404f84: afbe0038 sw s8,56(sp)
404f88: 03a0f025 move s8,sp
404f8c: afc00018 sw zero,24(s8)
404f90: 10000040 b 405094 <toplevel_fnc+0x118>
404f94: 00000000 nop
404f98: 83c30034 lb v1,52(s8)
404f9c: 2402005c li v0,92
404fa0: 14620022 bne v1,v0,40502c <toplevel_fnc+0xb0>
404fa4: 00000000 nop
404fa8: 8fc20018 lw v0,24(s8)
404fac: 00000000 nop
404fb0: 24420001 addiu v0,v0,1
404fb4: afc20018 sw v0,24(s8)
404fb8: 24040001 li a0,1
404fbc: 3c020041 lui v0,0x41
404fc0: 244260e0 addiu v0,v0,24800
404fc4: 00402825 move a1,v0
404fc8: 24060002 li a2,2
404fcc: 24020fa4 li v0,4004
404fd0: 0000000c syscall
404fd4: afc7001c sw a3,28(s8)
404fd8: afc20020 sw v0,32(s8)
404fdc: 8fc2001c lw v0,28(s8)
404fe0: 00000000 nop
404fe4: 14400004 bnez v0,404ff8 <toplevel_fnc+0x7c>
404fe8: 00000000 nop
404fec: 8fc20020 lw v0,32(s8)
404ff0: 10000002 b 404ffc <toplevel_fnc+0x80>
404ff4: 00000000 nop
404ff8: 2402ffff li v0,-1
404ffc: afc20024 sw v0,36(s8)
405000: 8fc20024 lw v0,36(s8)
405004: 00000000 nop
405008: 04410022 bgez v0,405094 <toplevel_fnc+0x118>
40500c: 00000000 nop
405010: 24040001 li a0,1
405014: 24020fa1 li v0,4001
405018: 0000000c syscall
40501c: afc7001c sw a3,28(s8)
405020: afc20028 sw v0,40(s8)
405024: 1000001b b 405094 <toplevel_fnc+0x118>
405028: 00000000 nop
40502c: 24040001 li a0,1
405030: 27c20034 addiu v0,s8,52
405034: 00402825 move a1,v0
405038: 24060001 li a2,1
40503c: 24020fa4 li v0,4004
405040: 0000000c syscall
405044: afc7001c sw a3,28(s8)
405048: afc2002c sw v0,44(s8)
40504c: 8fc2001c lw v0,28(s8)
405050: 00000000 nop
405054: 14400004 bnez v0,405068 <toplevel_fnc+0xec>
405058: 00000000 nop
40505c: 8fc2002c lw v0,44(s8)
405060: 10000002 b 40506c <toplevel_fnc+0xf0>
405064: 00000000 nop
405068: 2402ffff li v0,-1
40506c: afc20024 sw v0,36(s8)
405070: 8fc20024 lw v0,36(s8)
405074: 00000000 nop
405078: 04410006 bgez v0,405094 <toplevel_fnc+0x118>
40507c: 00000000 nop
405080: 24040001 li a0,1
405084: 24020fa1 li v0,4001
405088: 0000000c syscall
40508c: afc7001c sw a3,28(s8)
405090: afc20030 sw v0,48(s8)
405094: 00002025 move a0,zero
405098: 0c1013b4 jal 404ed0 <subroutine_fnc>
40509c: 00000000 nop
4050a0: 00021600 sll v0,v0,0x18
4050a4: 00021603 sra v0,v0,0x18
4050a8: a3c20034 sb v0,52(s8)
4050ac: 83c20034 lb v0,52(s8)
4050b0: 00000000 nop
4050b4: 1c40ffb8 bgtz v0,404f98 <toplevel_fnc+0x1c>
4050b8: 00000000 nop
4050bc: 8fc20018 lw v0,24(s8)
4050c0: 03c0e825 move sp,s8
4050c4: 8fbf003c lw ra,60(sp)
4050c8: 8fbe0038 lw s8,56(sp)
4050cc: 27bd0040 addiu sp,sp,64
4050d0: 03e00008 jr ra
4050d4: 00000000 nop
program data
build/program-mips: file format elf32-tradbigmips
Contents of section my_data:
4160e0 5c5c0000 \\..
and I wrote it in C as:
int toplevel_fnc(void) {
int a = 0;
while(1) {
char c = subroutine_fnc(0);
if (c <= 0) {
return a;
}
if (c == 92) {
a++;
int d = write(1, "\\", 2);
if (d < 0) {
exit(1);
}
} else {
int e = write(1, &c, 1);
if (e < 0) {
exit(1);
}
}
}
return a;
}
and
int subroutine_fnc(int a) {
char c;
int b = read(a, &c, 1);
if (b < 0) {
exit(1);
} else if (b == 0) {
return 0;
}
return c;
}
I am feeling lost, and also kind of stupid for asking here, but I feel like there is a small mistake that I overlooked. I've been working on this for the past three days, and I can't find the solution on how to correctly convert MIPS to C.
Please, I would be very glad if anyone could help me out on what is wrong in my code.
Thank you.
The assembly program writes two backslashes, whereas the C write(1, "\\", 2) writes one backslash and one NUL, because \\ in a string literal denotes only one backslash; you meant to write(1, "\\\\", 2).
The char is unsigned - this makes another deviation, since at a place in the assembly program a byte is sign extended and later tested with bgtz, while in the C code
char c = subroutine_fnc(0);
if (c <= 0)
the if condition will be true only for c = 0. Use signed char c … instead.

What does %call16 and .reloc mean in mips?

I have converted a c code into mips32 using gcc compiler but there are some parts that I did not understand.
This is c code:
int main()
{
float fibSquared;
int F[10] = {0};
F[0] = 0;
F[1] = 1;
for(int i = 2; i < 10 ; i++)
F[i] = F[i-1] + F[i-2];
fibSquared = sqrt(F[9]);
printf("%f",fibSquared);
return 0;
}
This is mips code:
.file 1 ""
.section .mdebug.abi32
.previous
.nan legacy
.module fp=32
.module nooddspreg
.abicalls
.rdata
.align 2
$LC0:
.ascii "%f\000"
.text
.align 2
.globl main
.set nomips16
.set nomicromips
.ent main
.type main, #function
main:
.frame $fp,80,$31 # vars= 48, regs= 2/0, args= 16, gp= 8
.mask 0xc0000000,-4
.fmask 0x00000000,0
.set noreorder
.cpload $25
.set nomacro
addiu $sp,$sp,-80
sw $31,76($sp)
sw $fp,72($sp)
move $fp,$sp
.cprestore 16
movz $31,$31,$0
sw $0,32($fp)
sw $0,36($fp)
sw $0,40($fp)
sw $0,44($fp)
sw $0,48($fp)
sw $0,52($fp)
sw $0,56($fp)
sw $0,60($fp)
sw $0,64($fp)
sw $0,68($fp)
sw $0,32($fp)
li $2,1 # 0x1
sw $2,36($fp)
li $2,2 # 0x2
sw $2,24($fp)
b $L2
nop
$L3:
lw $2,24($fp)
nop
addiu $2,$2,-1
sll $2,$2,2
addiu $3,$fp,24
addu $2,$3,$2
lw $3,8($2)
lw $2,24($fp)
nop
addiu $2,$2,-2
sll $2,$2,2
addiu $4,$fp,24
addu $2,$4,$2
lw $2,8($2)
nop
addu $3,$3,$2
lw $2,24($fp)
nop
sll $2,$2,2
addiu $4,$fp,24
addu $2,$4,$2
sw $3,8($2)
lw $2,24($fp)
nop
addiu $2,$2,1
sw $2,24($fp)
$L2:
lw $2,24($fp)
nop
slt $2,$2,10
bne $2,$0,$L3
nop
lw $2,68($fp)
nop
mtc1 $2,$f0
nop
cvt.d.w $f0,$f0
mov.d $f12,$f0
lw $2,%call16(sqrt)($28)
nop
move $25,$2
.reloc 1f,R_MIPS_JALR,sqrt
1: jalr $25
nop
lw $28,16($fp)
cvt.s.d $f0,$f0
swc1 $f0,28($fp)
lwc1 $f0,28($fp)
nop
cvt.d.s $f0,$f0
mfc1 $7,$f0
mfc1 $6,$f1
lw $2,%got($LC0)($28)
nop
addiu $4,$2,%lo($LC0)
lw $2,%call16(printf)($28)
nop
move $25,$2
.reloc 1f,R_MIPS_JALR,printf
1: jalr $25
nop
lw $28,16($fp)
move $2,$0
move $sp,$fp
lw $31,76($sp)
lw $fp,72($sp)
addiu $sp,$sp,80
j $31
nop
.set macro
.set reorder
.end main
.size main, .-main
.ident "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609"
This is the part I could not understand:
lw $2,68($fp)
nop
mtc1 $2,$f0
nop
cvt.d.w $f0,$f0
mov.d $f12,$f0
lw $2,%call16(sqrt)($28)
nop
move $25,$2
.reloc 1f,R_MIPS_JALR,sqrt
1: jalr $25
nop
lw $28,16($fp)
cvt.s.d $f0,$f0
swc1 $f0,28($fp)
lwc1 $f0,28($fp)
nop
cvt.d.s $f0,$f0
mfc1 $7,$f0
mfc1 $6,$f1
lw $2,%got($LC0)($28)
nop
addiu $4,$2,%lo($LC0)
lw $2,%call16(printf)($28)
nop
move $25,$2
.reloc 1f,R_MIPS_JALR,printf
1: jalr $25
nop
lw $28,16($fp)
move $2,$0
move $sp,$fp
lw $31,76($sp)
lw $fp,72($sp)
addiu $sp,$sp,80
j $31
nop
.set macro
.set reorder
.end main
.size main, .-main
.ident "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609"
What does .reloc mean?
How does %call16 work?
What is the corresponding value of the variable fibSquared?
How the functions "printf" and "sqrt" are called and executed?
I think you take the same class I do because I have the same homework, so I am going to share what I understood myself, it may help.
For %call16, if you noticed between the brackets, the name that the C code uses from the included files such as printf from stdio.h, sqrt from math file, so it's clearly calling them so he can use them.
About the .reloc, I have noticed that they come after %call16 and the called function executed and is for relocating the memory, so I think it reorders the included files from any damage that may have happened.
The fibSquared value is located in mem[-12] (SW $3,8($2))$2=-20, then it's moved to $f0 by(mtc1 $2,$f0). In the instruction, the second par is the destination($f0). It's converted from int to float in(cvt.d.w $f0,$f0).
The sqrt executed in this part of the code:
lw $2,%call16(sqrt)($28) \\ in this particular
nop
move $25,$2
.reloc 1f,R_MIPS_JALR,sqrt
1: jalr $25
$25 at the beginning was chosen for cpload (.cpload $25)
** printf :
lw $2,%got($LC0)($28)
nop
addiu $4,$2,%lo($LC0)
lw $2,%call16(printf)($28)\\ in this particular
nop
move $25,$2
.reloc 1f,R_MIPS_JALR,printf
1: jalr $25

Can someone translate these C codes into mips assembly code

//Please transfer these C codes into Mips assembly,
//I need to do this in mips assembly,but I have troubles on doing array
#include <stdio.h>
#include <string.h>
int main(int argc, const char * argv[])
{
char str[100];
printf("Input the string: ");
scanf("%s", str);
int size = (int)strlen(str);
for(int i = 0; i < size + 2; i++)
{
printf("*");
}
printf("\n");
printf("*%s*\n", str);
for(int i = 0; i < size + 2; i++)
{
printf("*");
}
printf("\n");
return 0;
}
//Thanks
You could use this http://reliant.colab.duke.edu/c2mips/ trans of c to Mips assembly. And the following should be work.
.file 1 ""
.section .mdebug.abi32
.previous
.gnu_attribute 4, 1
.abicalls
.rdata
.align 2
$LC0:
.ascii "Input the string: \000"
.align 2
$LC1:
.ascii "%s\000"
.align 2
$LC2:
.ascii "*%s*\012\000"
.text
.align 2
.globl main
$LFB0 = .
.set nomips16
.ent main
.type main, #function
main:
.frame $fp,144,$31 # vars= 112, regs= 2/0, args= 16, gp= 8
.mask 0xc0000000,-4
.fmask 0x00000000,0
.set noreorder
.cpload $25
.set nomacro
addiu $sp,$sp,-144
$LCFI0:
sw $31,140($sp)
$LCFI1:
sw $fp,136($sp)
movz $31,$31,$0
$LCFI2:
move $fp,$sp
$LCFI3:
.cprestore 16
sw $4,144($fp)
sw $5,148($fp)
lw $2,%got($LC0)($28)
nop
addiu $4,$2,%lo($LC0)
lw $2,%call16(printf)($28)
nop
move $25,$2
jalr $25
nop
lw $28,16($fp)
addiu $2,$fp,36
lw $3,%got($LC1)($28)
nop
addiu $4,$3,%lo($LC1)
move $5,$2
lw $2,%call16(scanf)($28)
nop
move $25,$2
jalr $25
nop
lw $28,16($fp)
addiu $2,$fp,36
move $4,$2
lw $2,%call16(strlen)($28)
nop
move $25,$2
jalr $25
nop
lw $28,16($fp)
sw $2,32($fp)
sw $0,28($fp)
b $L2
nop
$L3:
li $4,42 # 0x2a
lw $2,%call16(putchar)($28)
nop
move $25,$2
jalr $25
nop
lw $28,16($fp)
lw $2,28($fp)
nop
addiu $2,$2,1
sw $2,28($fp)
$L2:
lw $2,32($fp)
nop
addiu $3,$2,2
lw $2,28($fp)
nop
slt $2,$2,$3
andi $2,$2,0x00ff
bne $2,$0,$L3
nop
li $4,10 # 0xa
lw $2,%call16(putchar)($28)
nop
move $25,$2
jalr $25
nop
lw $28,16($fp)
addiu $2,$fp,36
lw $3,%got($LC2)($28)
nop
addiu $4,$3,%lo($LC2)
move $5,$2
lw $2,%call16(printf)($28)
nop
move $25,$2
jalr $25
nop
lw $28,16($fp)
sw $0,24($fp)
b $L4
nop
$L5:
li $4,42 # 0x2a
lw $2,%call16(putchar)($28)
nop
move $25,$2
jalr $25
nop
lw $28,16($fp)
lw $2,24($fp)
nop
addiu $2,$2,1
sw $2,24($fp)
$L4:
lw $2,32($fp)
nop
addiu $3,$2,2
lw $2,24($fp)
nop
slt $2,$2,$3
andi $2,$2,0x00ff
bne $2,$0,$L5
nop
li $4,10 # 0xa
lw $2,%call16(putchar)($28)
nop
move $25,$2
jalr $25
nop
lw $28,16($fp)
move $2,$0
move $sp,$fp
lw $31,140($sp)
lw $fp,136($sp)
addiu $sp,$sp,144
j $31
nop
.set macro
.set reorder
.end main
$LFE0:
.size main, .-main
.section .eh_frame,"aw",#progbits
$Lframe1:
.4byte $LECIE1-$LSCIE1
$LSCIE1:
.4byte 0x0
.byte 0x1
.globl __gxx_personality_v0
.ascii "zP\000"
.uleb128 0x1
.sleb128 -4
.byte 0x1f
.uleb128 0x5
.byte 0x0
.4byte __gxx_personality_v0
.byte 0xc
.uleb128 0x1d
.uleb128 0x0
.align 2
$LECIE1:
$LSFDE1:
.4byte $LEFDE1-$LASFDE1
$LASFDE1:
.4byte $LASFDE1-$Lframe1
.4byte $LFB0
.4byte $LFE0-$LFB0
.uleb128 0x0
.byte 0x4
.4byte $LCFI0-$LFB0
.byte 0xe
.uleb128 0x90
.byte 0x4
.4byte $LCFI2-$LCFI0
.byte 0x11
.uleb128 0x1e
.sleb128 2
.byte 0x11
.uleb128 0x1f
.sleb128 1
.byte 0x4
.4byte $LCFI3-$LCFI2
.byte 0xd
.uleb128 0x1e
.align 2
$LEFDE1:
.ident "GCC: (Debian 4.4.5-8) 4.4.5"

Translating a C statement into MIPS assembly instructions?

I have another homework question that, like the last question I asked on this site, wasn't explained well by the teacher nor the textbook. Here's the question:
Translate this C statement into MIPS assembly instructions:
B[8] = A[i-j];
Assume variables f, g, h, i and j and are assigned to registers $s0, $s1, $s2, $s3, and $s4, respectively. Assume the base addresses of the arrays A and B are in registers $s6 and $s7, respectively.
Now, where I'm stuck is adding the two variables and using the result as an offset. So far, I have the following:
sub $t0, $s3, $s4 # add values to get offset amount, store in $t0
sll $t1, $t0,2 # multiply the offset by 4, store in $t1
Now, I don't know if I can use $t1 as an offset to access that array element. It looks like the textbook only uses numbers (e.g. 4($s7)) instead of registers (e.g. $t1($s7)) What do I do next?
A compiler can only translate complete program, so here's a complete program that includes your instruction, with its translating into MIPS asembly instrution. I hope you can study what's being done here and draw some conclusions.
int main() {
int i = 3;
int j = 2;
int B[3] = {10, 20, 30};
int A[3] = {100, 200, 300};
B[8] = A[i-j];
}
MIPS for the above:
.file 1 "Cprogram.c"
# -G value = 8, Cpu = 3000, ISA = 1
# GNU C version cygnus-2.7.2-970404 (mips-mips-ecoff) compiled by GNU C version cygnus-2.7.2-970404.
# options passed: -msoft-float
# options enabled: -fpeephole -ffunction-cse -fkeep-static-consts
# -fpcc-struct-return -fcommon -fverbose-asm -fgnu-linker -msoft-float
# -meb -mcpu=3000
gcc2_compiled.:
__gnu_compiled_c:
.rdata
.align 2
$LC0:
.word 10
.word 20
.word 30
.align 2
$LC1:
.word 100
.word 200
.word 300
.text
.align 2
.globl main
.ent main
main:
.frame $fp,64,$31 # vars= 40, regs= 2/0, args= 16, extra= 0
.mask 0xc0000000,-4
.fmask 0x00000000,0
subu $sp,$sp,64
sw $31,60($sp)
sw $fp,56($sp)
move $fp,$sp
jal __main
li $2,3 # 0x00000003
sw $2,16($fp)
li $2,2 # 0x00000002
sw $2,20($fp)
addu $2,$fp,24
la $3,$LC0
lw $4,0($3)
lw $5,4($3)
lw $6,8($3)
sw $4,0($2)
sw $5,4($2)
sw $6,8($2)
addu $2,$fp,40
la $3,$LC1
lw $4,0($3)
lw $5,4($3)
lw $6,8($3)
sw $4,0($2)
sw $5,4($2)
sw $6,8($2)
lw $2,16($fp)
lw $3,20($fp)
subu $2,$2,$3
move $3,$2
sll $2,$3,2
addu $3,$fp,16
addu $2,$2,$3
addu $3,$2,24
lw $2,0($3)
sw $2,56($fp)
$L1:
move $sp,$fp # sp not trusted here
lw $31,60($sp)
lw $fp,56($sp)
addu $sp,$sp,64
j $31
.end main

Resources