@@ -81,8 +81,7 @@ struct _asm_x64_t {
8181 byte * code_base ;
8282 byte dummy_data [8 ];
8383
84- int next_label ;
85- int max_num_labels ;
84+ uint max_num_labels ;
8685 int * label_offsets ;
8786};
8887
@@ -98,15 +97,16 @@ void *alloc_mem(uint req_size, uint *alloc_size, bool is_exec) {
9897 return ptr ;
9998}
10099
101- asm_x64_t * asm_x64_new () {
100+ asm_x64_t * asm_x64_new (uint max_num_labels ) {
102101 asm_x64_t * as ;
103102
104103 as = m_new (asm_x64_t , 1 );
105104 as -> pass = 0 ;
106105 as -> code_offset = 0 ;
107106 as -> code_size = 0 ;
108107 as -> code_base = NULL ;
109- as -> label_offsets = NULL ;
108+ as -> max_num_labels = max_num_labels ;
109+ as -> label_offsets = m_new (int , max_num_labels );
110110
111111 return as ;
112112}
@@ -134,29 +134,19 @@ void asm_x64_free(asm_x64_t* as, bool free_code) {
134134void asm_x64_start_pass (asm_x64_t * as , int pass ) {
135135 as -> pass = pass ;
136136 as -> code_offset = 0 ;
137- as -> next_label = 1 ;
138- if (pass == ASM_X64_PASS_1 ) {
139- as -> max_num_labels = 0 ;
140- } else {
141- if (pass == ASM_X64_PASS_2 ) {
142- memset (as -> label_offsets , -1 , as -> max_num_labels * sizeof (int ));
143- }
137+ if (pass == ASM_X64_PASS_2 ) {
138+ // reset all labels
139+ memset (as -> label_offsets , -1 , as -> max_num_labels * sizeof (int ));
144140 }
145141}
146142
147143void asm_x64_end_pass (asm_x64_t * as ) {
148- if (as -> pass == ASM_X64_PASS_1 ) {
149- // calculate number of labels need
150- if (as -> next_label > as -> max_num_labels ) {
151- as -> max_num_labels = as -> next_label ;
152- }
153- as -> label_offsets = m_new (int , as -> max_num_labels );
154- } else if (as -> pass == ASM_X64_PASS_2 ) {
144+ if (as -> pass == ASM_X64_PASS_2 ) {
155145 // calculate size of code in bytes
156146 as -> code_size = as -> code_offset ;
157- as -> code_base = m_new (byte , as -> code_size );
158- // uint actual_alloc;
159- // as->code_base = alloc_mem(as->code_size, &actual_alloc, true);
147+ // as->code_base = m_new(byte, as->code_size); need to allocale executable memory
148+ uint actual_alloc ;
149+ as -> code_base = alloc_mem (as -> code_size , & actual_alloc , true);
160150 printf ("code_size: %u\n" , as -> code_size );
161151 }
162152
@@ -458,70 +448,65 @@ void asm_x64_setcc_r8(asm_x64_t* as, int jcc_type, int dest_r8) {
458448 asm_x64_write_byte_3 (as , OPCODE_SETCC_RM8_A , OPCODE_SETCC_RM8_B | jcc_type , MODRM_R64 (0 ) | MODRM_RM_REG | MODRM_RM_R64 (dest_r8 ));
459449}
460450
461- int asm_x64_label_new (asm_x64_t * as ) {
462- return as -> next_label ++ ;
463- }
464-
465451void asm_x64_label_assign (asm_x64_t * as , int label ) {
466- if (as -> pass > ASM_X64_PASS_1 ) {
467- assert (label < as -> max_num_labels );
468- if (as -> pass == ASM_X64_PASS_2 ) {
469- // assign label offset
470- assert (as -> label_offsets [label ] == -1 );
471- as -> label_offsets [label ] = as -> code_offset ;
472- } else if (as -> pass == ASM_X64_PASS_3 ) {
473- // ensure label offset has not changed from PASS_2 to PASS_3
474- //printf("l%d: (at %d=%ld)\n", label, as->label_offsets[label], as->code_offset);
475- assert (as -> label_offsets [label ] == as -> code_offset );
476- }
452+ assert (label < as -> max_num_labels );
453+ if (as -> pass == ASM_X64_PASS_2 ) {
454+ // assign label offset
455+ assert (as -> label_offsets [label ] == -1 );
456+ as -> label_offsets [label ] = as -> code_offset ;
457+ } else if (as -> pass == ASM_X64_PASS_3 ) {
458+ // ensure label offset has not changed from PASS_2 to PASS_3
459+ //printf("l%d: (at %d=%ld)\n", label, as->label_offsets[label], as->code_offset);
460+ assert (as -> label_offsets [label ] == as -> code_offset );
477461 }
478462}
479463
480- void asm_x64_jmp_label (asm_x64_t * as , int label ) {
481- if ( as -> pass > ASM_X64_PASS_1 ) {
482- int dest = as -> label_offsets [label ];
483- int rel = dest - as -> code_offset ;
484- if ( dest >= 0 && rel < 0 ) {
485- // is a backwards jump, so we know the size of the jump on the first pass
486- // calculate rel assuming 8 bit relative jump
487- rel -= 2 ;
488- if ( SIGNED_FIT8 ( rel ) ) {
489- asm_x64_write_byte_2 ( as , OPCODE_JMP_REL8 , rel & 0xff );
490- } else {
491- rel + = 2 ;
492- goto large_jump ;
493- }
464+ static int get_label_dest (asm_x64_t * as , int label ) {
465+ assert ( label < as -> max_num_labels );
466+ return as -> label_offsets [label ];
467+ }
468+
469+ void asm_x64_jmp_label ( asm_x64_t * as , int label ) {
470+ int dest = get_label_dest ( as , label );
471+ int rel = dest - as -> code_offset ;
472+ if ( dest >= 0 && rel < 0 ) {
473+ // is a backwards jump, so we know the size of the jump on the first pass
474+ // calculate rel assuming 8 bit relative jump
475+ rel - = 2 ;
476+ if ( SIGNED_FIT8 ( rel )) {
477+ asm_x64_write_byte_2 ( as , OPCODE_JMP_REL8 , rel & 0xff );
494478 } else {
495- // is a forwards jump, so need to assume it's large
496- large_jump :
497- rel -= 5 ;
498- asm_x64_write_byte_1 (as , OPCODE_JMP_REL32 );
499- asm_x64_write_word32 (as , rel );
479+ rel += 2 ;
480+ goto large_jump ;
500481 }
482+ } else {
483+ // is a forwards jump, so need to assume it's large
484+ large_jump :
485+ rel -= 5 ;
486+ asm_x64_write_byte_1 (as , OPCODE_JMP_REL32 );
487+ asm_x64_write_word32 (as , rel );
501488 }
502489}
503490
504- void asm_x64_jcc_label (asm_x64_t * as , int jcc_type , int label ) {
505- if (as -> pass > ASM_X64_PASS_1 ) {
506- int dest = as -> label_offsets [label ];
507- int rel = dest - as -> code_offset ;
508- if (dest >= 0 && rel < 0 ) {
509- // is a backwards jump, so we know the size of the jump on the first pass
510- // calculate rel assuming 8 bit relative jump
511- rel -= 2 ;
512- if (SIGNED_FIT8 (rel )) {
513- asm_x64_write_byte_2 (as , OPCODE_JCC_REL8 | jcc_type , rel & 0xff );
514- } else {
515- rel += 2 ;
516- goto large_jump ;
517- }
491+ void asm_x64_jcc_label (asm_x64_t * as , int jcc_type , int label ) {
492+ int dest = get_label_dest (as , label );
493+ int rel = dest - as -> code_offset ;
494+ if (dest >= 0 && rel < 0 ) {
495+ // is a backwards jump, so we know the size of the jump on the first pass
496+ // calculate rel assuming 8 bit relative jump
497+ rel -= 2 ;
498+ if (SIGNED_FIT8 (rel )) {
499+ asm_x64_write_byte_2 (as , OPCODE_JCC_REL8 | jcc_type , rel & 0xff );
518500 } else {
519- // is a forwards jump, so need to assume it's large
520- large_jump :
521- rel -= 6 ;
522- asm_x64_write_byte_2 (as , OPCODE_JCC_REL32_A , OPCODE_JCC_REL32_B | jcc_type );
523- asm_x64_write_word32 (as , rel );
501+ rel += 2 ;
502+ goto large_jump ;
524503 }
504+ } else {
505+ // is a forwards jump, so need to assume it's large
506+ large_jump :
507+ rel -= 6 ;
508+ asm_x64_write_byte_2 (as , OPCODE_JCC_REL32_A , OPCODE_JCC_REL32_B | jcc_type );
509+ asm_x64_write_word32 (as , rel );
525510 }
526511}
527512
0 commit comments