/SIC-XE-Assembler

Implementation of 2 Pass SIC-XE Assembler

Primary LanguageJava

Comparing C(x86) compile + linking with SIC-XE assembler + linking + loading

C(x86)

main.c contains

#include<stdio.h>

extern int fact(int i);

int main(void){
    int i = fact(5);
    printf("5 Factorial is %d\n", i);
    return 0;
}

fact.c contains:

int fact(int i){
    if(i == 0) 
        return 1;
    else
        return i * fact(i-1); 
}

Compile with debug information(to see C soruce and assembly interleved) and use objdump to see the generated object code: main.o and fact.o

$ gcc -c -g main.c 
$ objdump -dS main.o

main.o:     file format elf64-x86-64
Disassembly of section .text:

0000000000000000 <main>:
#include<stdio.h>

extern int fact(int i);

int main(void){
   0:	55                   	push   %rbp
   1:	48 89 e5             	mov    %rsp,%rbp
   4:	48 83 ec 10          	sub    $0x10,%rsp
    int i = fact(5);
   8:	bf 05 00 00 00       	mov    $0x5,%edi
   d:	e8 00 00 00 00       	callq  12 <main+0x12>
  12:	89 45 fc             	mov    %eax,-0x4(%rbp)
    printf("5 Factorial is %d\n", i);
  15:	8b 45 fc             	mov    -0x4(%rbp),%eax
  18:	89 c6                	mov    %eax,%esi
  1a:	bf 00 00 00 00       	mov    $0x0,%edi
  1f:	b8 00 00 00 00       	mov    $0x0,%eax
  24:	e8 00 00 00 00       	callq  29 <main+0x29>
    return 0;
  29:	b8 00 00 00 00       	mov    $0x0,%eax
}
  2e:	c9                   	leaveq 
  2f:	c3                   	retq  


$ gcc -c -g fact.c
$ objdump -dS fact.o

fact.o:     file format elf64-x86-64
Disassembly of section .text:

0000000000000000 <fact>:
int fact(int i){
   0:	55                   	push   %rbp
   1:	48 89 e5             	mov    %rsp,%rbp
   4:	48 83 ec 10          	sub    $0x10,%rsp
   8:	89 7d fc             	mov    %edi,-0x4(%rbp)
    if(i == 0) 
   b:	83 7d fc 00          	cmpl   $0x0,-0x4(%rbp)
   f:	75 07                	jne    18 <fact+0x18>
        return 1;
  11:	b8 01 00 00 00       	mov    $0x1,%eax
  16:	eb 11                	jmp    29 <fact+0x29>
    else
        return i * fact(i-1); 
  18:	8b 45 fc             	mov    -0x4(%rbp),%eax
  1b:	83 e8 01             	sub    $0x1,%eax
  1e:	89 c7                	mov    %eax,%edi
  20:	e8 00 00 00 00       	callq  25 <fact+0x25>
  25:	0f af 45 fc          	imul   -0x4(%rbp),%eax
}
  29:	c9                   	leaveq 
  2a:	c3                   	retq   

Lets invoke the linker to create the executable program, and use objdump again to see the object code from main and fact inside the executable.

$ gcc main.o fact.o

a.out:     file format elf64-x86-64
Disassembly of section .init:

00000000004003c8 <_init>:
  4003c8:	48 83 ec 08          	sub    $0x8,%rsp
  4003cc:	48 8b 05 25 0c 20 00 	mov    0x200c25(%rip),%rax        
  4003d3:	48 85 c0             	test   %rax,%rax
  4003d6:	74 05                	je     4003dd <_init+0x15>
  .
  .
  .
  40051b:	48 89 e5             	mov    %rsp,%rbp
  40051e:	ff d0                	callq  *%rax
  400520:	5d                   	pop    %rbp
  400521:	e9 7a ff ff ff       	jmpq   4004a0 <register_tm_clones>

0000000000400526 <main>:										# main function
  400526:	55                   	push   %rbp
  400527:	48 89 e5             	mov    %rsp,%rbp
  40052a:	48 83 ec 10          	sub    $0x10,%rsp
  40052e:	bf 05 00 00 00       	mov    $0x5,%edi
  400533:	e8 1e 00 00 00       	callq  400556 <fact>
  400538:	89 45 fc             	mov    %eax,-0x4(%rbp)
  40053b:	8b 45 fc             	mov    -0x4(%rbp),%eax
  40053e:	89 c6                	mov    %eax,%esi
  400540:	bf 14 06 40 00       	mov    $0x400614,%edi
  400545:	b8 00 00 00 00       	mov    $0x0,%eax
  40054a:	e8 b1 fe ff ff       	callq  400400 <printf@plt>
  40054f:	b8 00 00 00 00       	mov    $0x0,%eax
  400554:	c9                   	leaveq 
  400555:	c3                   	retq   

0000000000400556 <fact>:										# fact function
  400556:	55                   	push   %rbp
  400557:	48 89 e5             	mov    %rsp,%rbp
  40055a:	48 83 ec 10          	sub    $0x10,%rsp
  40055e:	89 7d fc             	mov    %edi,-0x4(%rbp)
  400561:	83 7d fc 00          	cmpl   $0x0,-0x4(%rbp)
  400565:	75 07                	jne    40056e <fact+0x18>
  400567:	b8 01 00 00 00       	mov    $0x1,%eax
  40056c:	eb 11                	jmp    40057f <fact+0x29>
  40056e:	8b 45 fc             	mov    -0x4(%rbp),%eax
  400571:	83 e8 01             	sub    $0x1,%eax
  400574:	89 c7                	mov    %eax,%edi
  400576:	e8 db ff ff ff       	callq  400556 <fact>
  40057b:	0f af 45 fc          	imul   -0x4(%rbp),%eax
  40057f:	c9                   	leaveq 
  400580:	c3                   	retq   
  400581:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
  400588:	00 00 00 
  40058b:	0f 1f 44 00 00       	nopl   0x0(%rax,%rax,1)

0000000000400590 <__libc_csu_init>:
  400590:	41 57                	push   %r15
  400592:	41 56                	push   %r14
  400594:	41 89 ff             	mov    %edi,%r15d
  .
  .
  .

0000000000400604 <_fini>:
  400604:	48 83 ec 08          	sub    $0x8,%rsp
  400608:	48 83 c4 08          	add    $0x8,%rsp
  40060c:	c3                   	retq 

To see the symbol table we will invoke nm a.out (GNU nm lists the symbols from object files objfile)

$ nm a.out
0000000000601038 B __bss_start
0000000000601038 b completed.7585
0000000000601028 D __data_start
0000000000601028 W data_start
0000000000400460 t deregister_tm_clones
00000000004004e0 t __do_global_dtors_aux
0000000000600e18 t __do_global_dtors_aux_fini_array_entry
0000000000601030 D __dso_handle
0000000000600e28 d _DYNAMIC
0000000000601038 D _edata
0000000000601040 B _end
0000000000400556 T fact
0000000000400604 T _fini
0000000000400500 t frame_dummy
0000000000600e10 t __frame_dummy_init_array_entry
0000000000400778 r __FRAME_END__
0000000000601000 d _GLOBAL_OFFSET_TABLE_
                 w __gmon_start__
0000000000400628 r __GNU_EH_FRAME_HDR
00000000004003c8 T _init
0000000000600e18 t __init_array_end
0000000000600e10 t __init_array_start
0000000000400610 R _IO_stdin_used
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
0000000000600e20 d __JCR_END__
0000000000600e20 d __JCR_LIST__
                 w _Jv_RegisterClasses
0000000000400600 T __libc_csu_fini
0000000000400590 T __libc_csu_init
                 U __libc_start_main@@GLIBC_2.2.5
0000000000400526 T main								
                 U printf@@GLIBC_2.2.5
00000000004004a0 t register_tm_clones
0000000000400430 T _start
0000000000601038 D __TMC_END__

Here you will note that main is at location 400526 and fact is at location 400556. The T in the second column means they are in the text section of our program. Which matches with our object dump.

SIC-XE

main.asm contains,

PROG		START		0
            EXTDEF		THREE
            EXTREF		ONE,TWO,FUNC
FIRST		+LDA		ONE
LOOP		+STA		TWO+3
            +J			LOOP
            +JSUB		FUNC
THREE		WORD		TWO-ONE
            END			FIRST

func.asm contains,

FUNC	START		0
		EXTDEF		ONE,TWO		
		EXTREF		THREE		
LOOP	+STA		THREE
		J		    LOOP
		RSUB					
ONE		WORD		8			
TWO		RESW		3			
FOUR	WORD		ONE
		END		    LOOP

Compile the assembler first, and then feed the asm files in the assembler.

$ javac Assembler/Main.java
$ java Assembler.Main main.asm

It will generate object code main.o

Reading from File : main.asm

*********** PASS 1 ***********

> Generated Intermediate File : main.int
00000   PROG        START               0
00000               EXTDEF              THREE
00000               EXTREF              ONE,TWO,FUNC
00000   FIRST       +LDA                ONE
00004   LOOP        +STA                TWO+3
00008               +J                  LOOP
0000C               +JSUB               FUNC
00010   THREE       WORD                TWO-ONE
00013               END                 FIRST

> Symbol Table
Symbol  Value   rflag   iflag   mflag
FIRS     00000     1       1       0
LOOP     00004     1       1       0
PROG     00000     1       1       0
THRE     00010     1       1       0

> Literal Table
Literal                 Value           length  address
(Literal Table is Empty)

Continue to see the output of Pass 2.


*********** PASS 2 ***********

> Adding object code to Intermediate File : main.txt
00000   PROG        START               0
00000               EXTDEF              THREE
00000               EXTREF              ONE,TWO,FUNC
00000   FIRST       +LDA                ONE                 03100000
00004   LOOP        +STA                TWO+3               0F100003
00008               +J                  LOOP                3F100004
0000C               +JSUB               FUNC                4B100000
00010   THREE       WORD                TWO-ONE             000000
00013               END                 FIRST

Continue to see the Updated Symbol table and Object Code

> Updated Symbol Table
Symbol  Value   rflag   iflag   mflag
FIRS     00000     1       1       0
FUNC     00000     0       0       0
LOOP     00004     1       1       0
ONE      00000     0       0       0
PROG     00000     1       1       0
THRE     00010     1       1       0
TWO      00000     0       0       0

> Generated Object Code : main.o
H^PROG^000000^000013
D^THRE^000010
R^ONE ^TWO ^FUNC
T^000000^13^03100000^0F100003^3F100004^4B100000^000000
M^000001^05^+ONE
M^000005^05^+TWO
M^000009^05^+PROG
M^00000D^05^+FUNC
M^000010^06^-ONE
M^000010^06^+TWO
E^000000

Feed func.asm to the assembler, and the assembler will generate func.o

Reading from File : func.asm

*********** PASS 1 ***********

> Generated Intermediate File : func.int
00000   FUNC        START               0
00000               EXTDEF              ONE,TWO
00000               EXTREF              THREE
00000   LOOP        +STA                THREE
00004               J                   LOOP
00007               RSUB
0000A   ONE         WORD                8
0000D   TWO         RESW                3
00016   FOUR        WORD                ONE
00019               END                 LOOP

> Symbol Table
Symbol  Value   rflag   iflag   mflag
FOUR     00016     1       1       0
FUNC     00000     1       1       0
LOOP     00000     1       1       0
ONE      0000A     1       1       0
TWO      0000D     1       1       0

> Literal Table
Literal                 Value           length  address
(Literal Table is Empty)

Continue to see the output of Pass 2.


*********** PASS 2 ***********

> Adding object code to Intermediate File : func.txt
00000   FUNC        START               0
00000               EXTDEF              ONE,TWO
00000               EXTREF              THREE
00000   LOOP        +STA                THREE               0F100000
00004               J                   LOOP                3F2FF9
00007               RSUB                                    4F0000
0000A   ONE         WORD                8                   000008
0000D   TWO         RESW                3
00016   FOUR        WORD                ONE                 00000A
00019               END                 LOOP

Continue to see the Updated Symbol table and Object Code

> Updated Symbol Table
Symbol  Value   rflag   iflag   mflag
FOUR     00016     1       1       0
FUNC     00000     1       1       0
LOOP     00000     1       1       0
ONE      0000A     1       1       0
THRE     00000     0       0       0
TWO      0000D     1       1       0

> Generated Object Code : func.o
H^FUNC^000000^000019
D^ONE ^00000A^TWO ^00000D
R^THRE
T^000000^0D^0F100000^3F2FF9^4F0000^000008
T^000016^03^00000A
M^000001^05^+THRE
M^000016^06^+FUNC
E^000000

We have our linker and loader invoked together. We will see the machine code laied out in the memory. The excution will start from 3860. The symbol table is added at the end.

$ java LinkerLoader.Main main.o func.o
Memory Layout :
      0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
386X 03 10 38 7d 0F 10 38 83 3F 10 38 64 4B 10 38 73
387X 10 03 84 0F 10 38 70 3F 2F F9 4F 00 00 00 00 08
388X ?? ?? ?? ?? ?? ?? ?? ?? ?? 00 38 7d ?? ?? ?? ??

Execution Address : 3860

External Symbol Table :
CSECT   SYMBOL  ADDR    CSADDR  LDADDR  LENGTH
FUNC                     3873              19
PROG                     3860              13
        THRE      10              3870
         ONE       a              387d
         TWO       d              3880