else
align = def_align; /* No alignment: use default */
- if (start & ~(align-1))
+ if (start & (align-1))
start = (start & ~(align-1)) + align;
*padamt = start - (base + *prevsectlen);
unsigned long start;
} bin_objfmt_output_info;
+static /*@only@*/ expr *
+bin_objfmt_expr_xform(/*@returned@*/ /*@only@*/ expr *e,
+ /*@unused@*/ /*@null@*/ void *d)
+{
+ int i;
+ /*@dependent@*/ section *sect;
+ /*@dependent@*/ /*@null@*/ bytecode *precbc;
+ /*@null@*/ intnum *dist;
+
+ for (i=0; i<e->numterms; i++) {
+ /* Transform symrecs that reference sections into
+ * start expr + intnum(dist).
+ */
+ if (e->terms[i].type == EXPR_SYM &&
+ symrec_get_label(e->terms[i].data.sym, §, &precbc) &&
+ (dist = common_calc_bc_dist(sect, NULL, precbc))) {
+ e->terms[i].type = EXPR_EXPR;
+ e->terms[i].data.expn =
+ expr_new(EXPR_ADD,
+ ExprExpr(expr_copy(section_get_start(sect))),
+ ExprInt(dist));
+ }
+ }
+
+ return e;
+}
+
static int
bin_objfmt_output_expr(expr **ep, unsigned char **bufp, unsigned long valsize,
/*@observer@*/ const section *sect,
* Other object formats need to generate their relocation list from here!
*/
- *ep = expr_simplify(*ep, common_calc_bc_dist);
+ *ep = expr_xform_neg_tree(*ep);
+ *ep = expr_level_tree(*ep, 1, 1, NULL, bin_objfmt_expr_xform, NULL, NULL);
/* Handle floating point expressions */
flt = expr_get_floatnum(ep);
--- /dev/null
+; test source file for assembling to binary files
+; build with:
+; yasm -f bin -o bintest.com bintest.asm
+
+; When run (as a DOS .COM file), this program should print
+; hello, world
+; on two successive lines, then exit cleanly.
+
+; This file should test the following:
+; [1] Define a text-section symbol
+; [2] Define a data-section symbol
+; [3] Define a BSS-section symbol
+; [4] Define a NASM local label
+; [5] Reference a NASM local label
+; [6] Reference a text-section symbol in the text section
+; [7] Reference a data-section symbol in the text section
+; [8] Reference a BSS-section symbol in the text section
+; [9] Reference a text-section symbol in the data section
+; [10] Reference a data-section symbol in the data section
+; [11] Reference a BSS-section symbol in the data section
+
+[BITS 16]
+[ORG 0x100]
+
+[SECTION .text]
+
+ jmp start ; [6]
+
+endX mov ax,0x4c00 ; [1]
+ int 0x21
+
+start mov byte [bss_sym],',' ; [1] [8]
+ mov bx,[bssptr] ; [7]
+ mov al,[bx]
+ mov bx,[dataptr] ; [7]
+ mov [bx],al
+ mov cx,2
+.loop mov dx,datasym ; [1] [4] [7]
+ mov ah,9
+ push cx
+ int 0x21
+ pop cx
+ loop .loop ; [5] [6]
+ mov bx,[textptr] ; [7]
+ jmp bx
+
+[SECTION .data]
+
+datasym db 'hello world', 13, 10, '$' ; [2]
+bssptr dw bss_sym ; [2] [11]
+dataptr dw datasym+5 ; [2] [10]
+textptr dw endX ; [2] [9]
+
+[SECTION .bss]
+
+bss_sym resb 1 ; [3]
--- /dev/null
+eb
+05
+b8
+00
+4c
+cd
+21
+c6
+06
+44
+01
+2c
+8b
+1e
+3b
+01
+8a
+07
+8b
+1e
+3d
+01
+88
+07
+b9
+02
+00
+ba
+2c
+01
+b4
+09
+51
+cd
+21
+59
+e2
+f5
+8b
+1e
+3f
+01
+ff
+e3
+68
+65
+6c
+6c
+6f
+20
+20
+77
+6f
+72
+6c
+64
+0d
+0a
+24
+44
+01
+31
+01
+02
+01
else
align = def_align; /* No alignment: use default */
- if (start & ~(align-1))
+ if (start & (align-1))
start = (start & ~(align-1)) + align;
*padamt = start - (base + *prevsectlen);
unsigned long start;
} bin_objfmt_output_info;
+static /*@only@*/ expr *
+bin_objfmt_expr_xform(/*@returned@*/ /*@only@*/ expr *e,
+ /*@unused@*/ /*@null@*/ void *d)
+{
+ int i;
+ /*@dependent@*/ section *sect;
+ /*@dependent@*/ /*@null@*/ bytecode *precbc;
+ /*@null@*/ intnum *dist;
+
+ for (i=0; i<e->numterms; i++) {
+ /* Transform symrecs that reference sections into
+ * start expr + intnum(dist).
+ */
+ if (e->terms[i].type == EXPR_SYM &&
+ symrec_get_label(e->terms[i].data.sym, §, &precbc) &&
+ (dist = common_calc_bc_dist(sect, NULL, precbc))) {
+ e->terms[i].type = EXPR_EXPR;
+ e->terms[i].data.expn =
+ expr_new(EXPR_ADD,
+ ExprExpr(expr_copy(section_get_start(sect))),
+ ExprInt(dist));
+ }
+ }
+
+ return e;
+}
+
static int
bin_objfmt_output_expr(expr **ep, unsigned char **bufp, unsigned long valsize,
/*@observer@*/ const section *sect,
* Other object formats need to generate their relocation list from here!
*/
- *ep = expr_simplify(*ep, common_calc_bc_dist);
+ *ep = expr_xform_neg_tree(*ep);
+ *ep = expr_level_tree(*ep, 1, 1, NULL, bin_objfmt_expr_xform, NULL, NULL);
/* Handle floating point expressions */
flt = expr_get_floatnum(ep);
--- /dev/null
+; test source file for assembling to binary files
+; build with:
+; yasm -f bin -o bintest.com bintest.asm
+
+; When run (as a DOS .COM file), this program should print
+; hello, world
+; on two successive lines, then exit cleanly.
+
+; This file should test the following:
+; [1] Define a text-section symbol
+; [2] Define a data-section symbol
+; [3] Define a BSS-section symbol
+; [4] Define a NASM local label
+; [5] Reference a NASM local label
+; [6] Reference a text-section symbol in the text section
+; [7] Reference a data-section symbol in the text section
+; [8] Reference a BSS-section symbol in the text section
+; [9] Reference a text-section symbol in the data section
+; [10] Reference a data-section symbol in the data section
+; [11] Reference a BSS-section symbol in the data section
+
+[BITS 16]
+[ORG 0x100]
+
+[SECTION .text]
+
+ jmp start ; [6]
+
+endX mov ax,0x4c00 ; [1]
+ int 0x21
+
+start mov byte [bss_sym],',' ; [1] [8]
+ mov bx,[bssptr] ; [7]
+ mov al,[bx]
+ mov bx,[dataptr] ; [7]
+ mov [bx],al
+ mov cx,2
+.loop mov dx,datasym ; [1] [4] [7]
+ mov ah,9
+ push cx
+ int 0x21
+ pop cx
+ loop .loop ; [5] [6]
+ mov bx,[textptr] ; [7]
+ jmp bx
+
+[SECTION .data]
+
+datasym db 'hello world', 13, 10, '$' ; [2]
+bssptr dw bss_sym ; [2] [11]
+dataptr dw datasym+5 ; [2] [10]
+textptr dw endX ; [2] [9]
+
+[SECTION .bss]
+
+bss_sym resb 1 ; [3]
--- /dev/null
+eb
+05
+b8
+00
+4c
+cd
+21
+c6
+06
+44
+01
+2c
+8b
+1e
+3b
+01
+8a
+07
+8b
+1e
+3d
+01
+88
+07
+b9
+02
+00
+ba
+2c
+01
+b4
+09
+51
+cd
+21
+59
+e2
+f5
+8b
+1e
+3f
+01
+ff
+e3
+68
+65
+6c
+6c
+6f
+20
+20
+77
+6f
+72
+6c
+64
+0d
+0a
+24
+44
+01
+31
+01
+02
+01