From: yu.dongliang <18588496441@163.com> Date: Wed, 28 Jan 2026 11:42:44 +0000 (+0800) Subject: asm: support .align and .org for naja X-Git-Url: http://baseworks.info/?a=commitdiff_plain;ds=inline;p=scf.git asm: support .align and .org for naja --- diff --git a/asm/naja.s b/asm/naja.s index 2aed373..3e3d376 100644 --- a/asm/naja.s +++ b/asm/naja.s @@ -10,6 +10,8 @@ main: mov r0, 0 pop lr ret +.align 3 +.org 508 1: call 0b .asciz "hello world\n" diff --git a/asm/scf_asm.c b/asm/scf_asm.c index 5fb2280..91ff6d5 100644 --- a/asm/scf_asm.c +++ b/asm/scf_asm.c @@ -144,6 +144,38 @@ int scf_asm_file(scf_asm_t* _asm, const char* path) return ret; } +int scf_asm_fill(scf_instruction_t** __inst, int n, int size, uint64_t imm) +{ + scf_instruction_t* inst = calloc(1, sizeof(scf_instruction_t)); + if (!inst) + return -ENOMEM; + + int i; + if (n * size <= sizeof(inst->code)) { + for (i = 0; i < n; i++) + memcpy(inst->code + i * size, (uint8_t*)&imm, size); + + inst->len = n * size; + } else { + inst->bin = scf_string_alloc(); + if (inst->bin) { + scf_instruction_free(inst); + return -ENOMEM; + } + + for (i = 0; i < n; i++) { + int ret = scf_string_cat_cstr_len(inst->bin, (uint8_t*)&imm, size); + if (ret < 0) { + scf_instruction_free(inst); + return -ENOMEM; + } + } + } + + *__inst = inst; + return 0; +} + int scf_asm_len(scf_vector_t* instructions) { scf_instruction_t* inst; diff --git a/asm/scf_asm.h b/asm/scf_asm.h index cb15a94..39b2132 100644 --- a/asm/scf_asm.h +++ b/asm/scf_asm.h @@ -66,6 +66,8 @@ int scf_asm_to_obj(scf_asm_t* _asm, const char* obj, const char* arch); int scf_asm_len(scf_vector_t* instructions); +int scf_asm_fill(scf_instruction_t** __inst, int n, int size, uint64_t imm); + static inline int __inst_data_is_reg(scf_inst_data_t* id) { if (!id->flag && id->base && 0 == id->imm_size) @@ -88,4 +90,18 @@ static inline int __lex_word_cmp(const void* v0, const void* v1) return scf_string_cmp(w0->text, w1->text); } +static inline void asm_inst_set_label(scf_instruction_t* inst, dfa_asm_t* d) +{ + if (d->label) { + inst->label = d->label; + d ->label = NULL; + } + + inst->align = d->align; + inst->org = d->org; + + d->align = 0; + d->org = 0; +} + #endif diff --git a/asm/scf_dfa_naja.c b/asm/scf_dfa_naja.c index 3bb2633..bab87d9 100644 --- a/asm/scf_dfa_naja.c +++ b/asm/scf_dfa_naja.c @@ -62,6 +62,7 @@ static int _naja_action_fill(scf_dfa_t* dfa, scf_vector_t* words, void* data) scf_lex_word_t* w = words->data[words->size - 1]; d->fill = w; + d->i = 0; return SCF_DFA_NEXT_WORD; } @@ -199,10 +200,7 @@ static int _naja_action_number(scf_dfa_t* dfa, scf_vector_t* words, void* data) inst->len = n; RISC_INST_ADD_CHECK(_asm->current, inst); - if (d->label) { - inst->label = d->label; - d ->label = NULL; - } + asm_inst_set_label(inst, d); } return SCF_DFA_NEXT_WORD; @@ -249,10 +247,7 @@ static int _naja_action_str(scf_dfa_t* dfa, scf_vector_t* words, void* data) } RISC_INST_ADD_CHECK(_asm->current, inst); - if (d->label) { - inst->label = d->label; - d ->label = NULL; - } + asm_inst_set_label(inst, d); return SCF_DFA_NEXT_WORD; } @@ -311,11 +306,7 @@ static int _naja_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* data return -ENOMEM; inst->len = 8; RISC_INST_ADD_CHECK(_asm->current, inst); - - if (d->label) { - inst->label = d->label; - d ->label = NULL; - } + asm_inst_set_label(inst, d); scf_rela_t* rela = calloc(1, sizeof(scf_rela_t)); if (!rela) @@ -742,52 +733,45 @@ static int _naja_action_LF(scf_dfa_t* dfa, scf_vector_t* words, void* data) if (ret < 0) return ret; - - if (d->label) { - inst->label = d->label; - d ->label = NULL; - } + asm_inst_set_label(inst, d); scf_instruction_print(inst); d->opcode = NULL; } else if (d->fill) { - if (d->i < 3) { - scf_loge(".fill needs 3 operands, file: %s, line: %d\n", d->fill->file->data, d->fill->line); - return SCF_DFA_ERROR; - } + if (SCF_LEX_WORD_ASM_ORG == d->fill->type) { + if (d->i < 1) { + scf_loge(".org needs 1 operand, file: %s, line: %d\n", d->fill->file->data, d->fill->line); + return SCF_DFA_ERROR; + } - int64_t n = d->operands[0].imm; - int64_t size = d->operands[1].imm; - uint64_t imm = d->operands[2].imm; - int64_t i; + d->org = d->operands[0].imm; - inst = calloc(1, sizeof(scf_instruction_t)); - if (!inst) - return -ENOMEM; + } else if (SCF_LEX_WORD_ASM_ALIGN == d->fill->type) { + if (d->i < 1) { + scf_loge(".align needs 1 operand, file: %s, line: %d\n", d->fill->file->data, d->fill->line); + return SCF_DFA_ERROR; + } - if (n * size <= sizeof(inst->code)) { - for (i = 0; i < n; i++) - memcpy(inst->code + i * size, (uint8_t*)&imm, size); + d->align = 1 << d->operands[0].imm; - inst->len = n * size; - } else { - inst->bin = scf_string_alloc(); - if (inst->bin) { - scf_instruction_free(inst); - return -ENOMEM; + } else if (SCF_LEX_WORD_ASM_FILL == d->fill->type) { + if (d->i < 3) { + scf_loge(".fill needs 3 operands, file: %s, line: %d\n", d->fill->file->data, d->fill->line); + return SCF_DFA_ERROR; } - for (i = 0; i < n; i++) { - int ret = scf_string_cat_cstr_len(inst->bin, (uint8_t*)&imm, size); - if (ret < 0) { - scf_instruction_free(inst); - return -ENOMEM; - } - } + int64_t n = d->operands[0].imm; + int64_t size = d->operands[1].imm; + uint64_t imm = d->operands[2].imm; + + if (scf_asm_fill(&inst, n, size, imm) < 0) + return SCF_DFA_ERROR; + + RISC_INST_ADD_CHECK(_asm->current, inst); + asm_inst_set_label(inst, d); } - RISC_INST_ADD_CHECK(_asm->current, inst); d->fill = NULL; } @@ -834,6 +818,9 @@ int _naja_set_offset_for_jmps(scf_vector_t* text) int i; int j; + if (scf_asm_len(text) < 0) + return -1; + for (i = 0; i < text->size; i++) { inst = text->data[i]; @@ -877,16 +864,6 @@ int _naja_set_offset_for_jmps(scf_vector_t* text) scf_loge("number label %d NOT found\n", label); return -1; } - - for ( ; j < i; j++) { - dst = text->data[j]; - - if (dst->len > 0) - bytes -= dst->len; - else if (dst->bin) - bytes -= dst->bin->len; - } - } else if (2 == flag) { for (j = i; j < text->size; j++) { dst = text->data[j]; @@ -897,11 +874,6 @@ int _naja_set_offset_for_jmps(scf_vector_t* text) inst->next = dst; break; } - - if (dst->len > 0) - bytes += dst->len; - else if (dst->bin) - bytes += dst->bin->len; } if (j >= text->size) { @@ -911,6 +883,8 @@ int _naja_set_offset_for_jmps(scf_vector_t* text) } else continue; + bytes = inst->next->offset - inst->offset; + naja_set_jmp_offset(inst, bytes); } @@ -923,6 +897,8 @@ static int _dfa_init_module_naja(scf_dfa_t* dfa) SCF_DFA_MODULE_NODE(dfa, naja, data, scf_asm_is_data, _naja_action_data); SCF_DFA_MODULE_NODE(dfa, naja, global, scf_asm_is_global, _naja_action_global); SCF_DFA_MODULE_NODE(dfa, naja, fill, scf_asm_is_fill, _naja_action_fill); + SCF_DFA_MODULE_NODE(dfa, naja, align, scf_asm_is_align, _naja_action_fill); + SCF_DFA_MODULE_NODE(dfa, naja, org, scf_asm_is_org, _naja_action_fill); SCF_DFA_MODULE_NODE(dfa, naja, type, scf_asm_is_type, _naja_action_type); SCF_DFA_MODULE_NODE(dfa, naja, str, scf_asm_is_str, _naja_action_str); @@ -955,6 +931,8 @@ static int _dfa_init_syntax_naja(scf_dfa_t* dfa) SCF_DFA_GET_MODULE_NODE(dfa, naja, data, data); SCF_DFA_GET_MODULE_NODE(dfa, naja, global, global); SCF_DFA_GET_MODULE_NODE(dfa, naja, fill, fill); + SCF_DFA_GET_MODULE_NODE(dfa, naja, align, align); + SCF_DFA_GET_MODULE_NODE(dfa, naja, org, org); SCF_DFA_GET_MODULE_NODE(dfa, naja, identity, identity); SCF_DFA_GET_MODULE_NODE(dfa, naja, colon, colon); @@ -977,6 +955,8 @@ static int _dfa_init_syntax_naja(scf_dfa_t* dfa) scf_vector_add(dfa->syntaxes, data); scf_vector_add(dfa->syntaxes, global); scf_vector_add(dfa->syntaxes, fill); + scf_vector_add(dfa->syntaxes, align); + scf_vector_add(dfa->syntaxes, org); scf_vector_add(dfa->syntaxes, opcode); scf_vector_add(dfa->syntaxes, identity); @@ -1034,8 +1014,9 @@ static int _dfa_init_syntax_naja(scf_dfa_t* dfa) scf_dfa_node_add_child(rp, comma); scf_dfa_node_add_child(rp, LF); - // .fill - scf_dfa_node_add_child(fill, number); + scf_dfa_node_add_child(fill, number); // .fill + scf_dfa_node_add_child(align, number); // .align + scf_dfa_node_add_child(org, number); // .org // .global scf_dfa_node_add_child(global, identity); diff --git a/asm/scf_dfa_x64.c b/asm/scf_dfa_x64.c index 007da3c..5aae34c 100644 --- a/asm/scf_dfa_x64.c +++ b/asm/scf_dfa_x64.c @@ -199,10 +199,7 @@ static int _x64_action_number(scf_dfa_t* dfa, scf_vector_t* words, void* data) inst->len = n; X64_INST_ADD_CHECK(_asm->current, inst, NULL); - if (d->label) { - inst->label = d->label; - d ->label = NULL; - } + asm_inst_set_label(inst, d); } return SCF_DFA_NEXT_WORD; @@ -249,10 +246,7 @@ static int _x64_action_str(scf_dfa_t* dfa, scf_vector_t* words, void* data) } X64_INST_ADD_CHECK(_asm->current, inst, NULL); - if (d->label) { - inst->label = d->label; - d ->label = NULL; - } + asm_inst_set_label(inst, d); return SCF_DFA_NEXT_WORD; } @@ -311,11 +305,7 @@ static int _x64_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* data) return -ENOMEM; inst->len = 8; X64_INST_ADD_CHECK(_asm->current, inst, NULL); - - if (d->label) { - inst->label = d->label; - d ->label = NULL; - } + asm_inst_set_label(inst, d); scf_rela_t* rela = calloc(1, sizeof(scf_rela_t)); if (!rela) @@ -715,17 +705,7 @@ static int _x64_action_LF(scf_dfa_t* dfa, scf_vector_t* words, void* data) if (ret < 0) return ret; - - if (d->label) { - inst->label = d->label; - d ->label = NULL; - } - - inst->align = d->align; - inst->org = d->org; - - d->align = 0; - d->org = 0; + asm_inst_set_label(inst, d); scf_instruction_print(inst); d->opcode = NULL; @@ -756,40 +736,12 @@ static int _x64_action_LF(scf_dfa_t* dfa, scf_vector_t* words, void* data) int64_t n = d->operands[0].imm; int64_t size = d->operands[1].imm; uint64_t imm = d->operands[2].imm; - int64_t i; - - inst = calloc(1, sizeof(scf_instruction_t)); - if (!inst) - return -ENOMEM; - if (n * size <= sizeof(inst->code)) { - for (i = 0; i < n; i++) - memcpy(inst->code + i * size, (uint8_t*)&imm, size); - - inst->len = n * size; - } else { - inst->bin = scf_string_alloc(); - if (inst->bin) { - scf_instruction_free(inst); - return -ENOMEM; - } - - for (i = 0; i < n; i++) { - int ret = scf_string_cat_cstr_len(inst->bin, (uint8_t*)&imm, size); - if (ret < 0) { - scf_instruction_free(inst); - return -ENOMEM; - } - } - } + if (scf_asm_fill(&inst, n, size, imm) < 0) + return SCF_DFA_ERROR; X64_INST_ADD_CHECK(_asm->current, inst, NULL); - - inst->align = d->align; - inst->org = d->org; - - d->align = 0; - d->org = 0; + asm_inst_set_label(inst, d); } d->fill = NULL;