NASM - The Netwide Assembler

NASM Forum => Using NASM => Topic started by: stanleylai on November 21, 2010, 12:57:05 PM

Title: A compile problem.
Post by: stanleylai on November 21, 2010, 12:57:05 PM
Hi,

When I compiled the following code with nasm-2.09.03, it generated a large size .com file. Please check it.

nasm pmtest3.asm -o pmtest3.com

pm.inc
Code: [Select]
;----------------------------------------------------------------------------
DA_32 EQU 4000h ; 32 ??

DA_DPL0 EQU   00h ; DPL = 0
DA_DPL1 EQU   20h ; DPL = 1
DA_DPL2 EQU   40h ; DPL = 2
DA_DPL3 EQU   60h ; DPL = 3
;----------------------------------------------------------------------------
; ???????????
;----------------------------------------------------------------------------
DA_DR EQU 90h ; ???????????
DA_DRW EQU 92h ; ????????????
DA_DRWA EQU 93h ; ???????????????
DA_C EQU 98h ; ????????????
DA_CR EQU 9Ah ; ??????????????
DA_CCO EQU 9Ch ; ??????????????
DA_CCOR EQU 9Eh ; ????????????????
;----------------------------------------------------------------------------
; ???????????
;----------------------------------------------------------------------------
DA_LDT EQU   82h ; ??????????
DA_TaskGate EQU   85h ; ??????
DA_386TSS EQU   89h ; ?? 386 ????????
DA_386CGate EQU   8Ch ; 386 ??????
DA_386IGate EQU   8Eh ; 386 ??????
DA_386TGate EQU   8Fh ; 386 ??????
;----------------------------------------------------------------------------


; ?????:
;         ?????????????????????????????????????????????????
;         ? 15 ? 14 ? 13 ? 12 ? 11 ? 10 ? 9  ? 8  ? 7  ? 6  ? 5  ? 4  ? 3  ? 2  ? 1  ? 0  ?
;         ?????????????????????????????????????????????????
;         ?                                 ?????                                 ? TI ?   RPL    ?
;         ?????????????????????????????????????????????????
;
; RPL(Requested Privilege Level): ?????????????
;
; TI(Table Indicator): ?????????
; TI=0 ?????????GDT???????
; TI=1 ?????????LDT???????
;

;----------------------------------------------------------------------------
; ????????
; ??:
;       SA_  : Selector Attribute

SA_RPL0 EQU 0 ; ?
SA_RPL1 EQU 1 ; ? RPL
SA_RPL2 EQU 2 ; ?
SA_RPL3 EQU 3 ; ?

SA_TIG EQU 0 ; ?TI
SA_TIL EQU 4 ; ?
;----------------------------------------------------------------------------



; ? ------------------------------------------------------------------------------------------------------
;
; ???
; usage: Descriptor Base, Limit, Attr
;        Base:  dd
;        Limit: dd (low 20 bits available)
;        Attr:  dw (lower 4 bits of higher byte are always 0)
%macro Descriptor 3
dw %2 & 0FFFFh ; ??? 1 (2 ??)
dw %1 & 0FFFFh ; ??? 1 (2 ??)
db (%1 >> 16) & 0FFh ; ??? 2 (1 ??)
dw ((%2 >> 8) & 0F00h) | (%3 & 0F0FFh) ; ?? 1 + ??? 2 + ?? 2 (2 ??)
db (%1 >> 24) & 0FFh ; ??? 3 (1 ??)
%endmacro ; ? 8 ??
;
; ?
; usage: Gate Selector, Offset, DCount, Attr
;        Selector:  dw
;        Offset:    dd
;        DCount:    db
;        Attr:      db
%macro Gate 4
dw (%2 & 0FFFFh) ; ?? 1 (2 ??)
dw %1 ; ??? (2 ??)
dw (%3 & 1Fh) | ((%4 << 8) & 0FF00h) ; ?? (2 ??)
dw ((%2 >> 16) & 0FFFFh) ; ?? 2 (2 ??)
%endmacro ; ? 8 ??
; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


pmtest3.asm
Code: [Select]
; ==========================================
; pmtest3.asm
; ?????nasm pmtest3.asm -o pmtest3.com
; ==========================================

%include "pm.inc" ; ??, ??, ??????

org 0100h
jmp LABEL_BEGIN

[SECTION .gdt]
; GDT
;                                         ???,       ???     , ??
LABEL_GDT:         Descriptor       0,                 0, 0      ; ????
LABEL_DESC_NORMAL: Descriptor       0,            0ffffh, DA_DRW ; Normal ???
LABEL_DESC_CODE32: Descriptor       0,  SegCode32Len - 1, DA_C + DA_32 ; ???????, 32
LABEL_DESC_CODE16: Descriptor       0,            0ffffh, DA_C ; ???????, 16
LABEL_DESC_DATA:   Descriptor       0,       DataLen - 1, DA_DRW+DA_DPL1 ; Data
LABEL_DESC_STACK:  Descriptor       0,        TopOfStack, DA_DRWA + DA_32; Stack, 32 ?
LABEL_DESC_LDT:    Descriptor       0,        LDTLen - 1, DA_LDT ; LDT
LABEL_DESC_VIDEO:  Descriptor 0B8000h,            0ffffh, DA_DRW ; ?????????
; GDT ??

GdtLen equ $ - LABEL_GDT ; GDT??
GdtPtr dw GdtLen - 1 ; GDT??
dd 0 ; GDT???

; GDT ???
SelectorNormal equ LABEL_DESC_NORMAL - LABEL_GDT
SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT
SelectorCode16 equ LABEL_DESC_CODE16 - LABEL_GDT
SelectorData equ LABEL_DESC_DATA - LABEL_GDT
SelectorStack equ LABEL_DESC_STACK - LABEL_GDT
SelectorLDT equ LABEL_DESC_LDT - LABEL_GDT
SelectorVideo equ LABEL_DESC_VIDEO - LABEL_GDT
; END of [SECTION .gdt]

[SECTION .data1] ; ???
ALIGN 32
[BITS 32]
LABEL_DATA:
SPValueInRealMode dw 0
; ???
PMMessage: db "In Protect Mode now. ^-^", 0 ; ?????????????
OffsetPMMessage equ PMMessage - $$
StrTest: db "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0
OffsetStrTest equ StrTest - $$
DataLen equ $ - LABEL_DATA
; END of [SECTION .data1]


; ?????
[SECTION .gs]
ALIGN 32
[BITS 32]
LABEL_STACK:
times 512 db 0

TopOfStack equ $ - LABEL_STACK - 1

; END of [SECTION .gs]


[SECTION .s16]
[BITS 16]
LABEL_BEGIN:
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0100h

mov [LABEL_GO_BACK_TO_REAL+3], ax
mov [SPValueInRealMode], sp

; ??? 16 ????????
mov ax, cs
movzx eax, ax
shl eax, 4
add eax, LABEL_SEG_CODE16
mov word [LABEL_DESC_CODE16 + 2], ax
shr eax, 16
mov byte [LABEL_DESC_CODE16 + 4], al
mov byte [LABEL_DESC_CODE16 + 7], ah

; ??? 32 ????????
xor eax, eax
mov ax, cs
shl eax, 4
add eax, LABEL_SEG_CODE32
mov word [LABEL_DESC_CODE32 + 2], ax
shr eax, 16
mov byte [LABEL_DESC_CODE32 + 4], al
mov byte [LABEL_DESC_CODE32 + 7], ah

; ?????????
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_DATA
mov word [LABEL_DESC_DATA + 2], ax
shr eax, 16
mov byte [LABEL_DESC_DATA + 4], al
mov byte [LABEL_DESC_DATA + 7], ah

; ?????????
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_STACK
mov word [LABEL_DESC_STACK + 2], ax
shr eax, 16
mov byte [LABEL_DESC_STACK + 4], al
mov byte [LABEL_DESC_STACK + 7], ah

; ??? LDT ? GDT ?????
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_LDT
mov word [LABEL_DESC_LDT + 2], ax
shr eax, 16
mov byte [LABEL_DESC_LDT + 4], al
mov byte [LABEL_DESC_LDT + 7], ah

; ??? LDT ?????
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_CODE_A
mov word [LABEL_LDT_DESC_CODEA + 2], ax
shr eax, 16
mov byte [LABEL_LDT_DESC_CODEA + 4], al
mov byte [LABEL_LDT_DESC_CODEA + 7], ah

; ??? GDTR ???
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_GDT ; eax <- gdt ???
mov dword [GdtPtr + 2], eax ; [GdtPtr + 2] <- gdt ???

; ?? GDTR
lgdt [GdtPtr]

; ???
cli

; ?????A20
in al, 92h
or al, 00000010b
out 92h, al

; ?????????
mov eax, cr0
or eax, 1
mov cr0, eax

; ????????
jmp dword SelectorCode32:0 ; ??????? SelectorCode32 ?? cs, ???? Code32Selector:0  ?

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

LABEL_REAL_ENTRY: ; ????????????????
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax

mov sp, [SPValueInRealMode]

in al, 92h ; ?
and al, 11111101b ; ? ?? A20 ???
out 92h, al ; ?

sti ; ???

mov ax, 4c00h ; ?
int 21h ; ??? DOS
; END of [SECTION .s16]


[SECTION .s32]; 32 ?????. ??????.
[BITS 32]

LABEL_SEG_CODE32:
mov ax, SelectorData
mov ds, ax ; ??????
mov ax, SelectorVideo
mov gs, ax ; ??????

mov ax, SelectorStack
mov ss, ax ; ??????

mov esp, TopOfStack


; ?????????
mov ah, 0Ch ; 0000: ??    1100: ??
xor esi, esi
xor edi, edi
mov esi, OffsetPMMessage ; ?????
mov edi, (80 * 10 + 0) * 2 ; ?????????? 10 ?, ? 0 ??
cld
.1:
lodsb
test al, al
jz .2
mov [gs:edi], ax
add edi, 2
jmp .1
.2: ; ????

call DispReturn

; Load LDT
mov ax, SelectorLDT
lldt ax

jmp SelectorLDTCodeA:0 ; ??????

; ------------------------------------------------------------------------
DispReturn:
push eax
push ebx
mov eax, edi
mov bl, 160
div bl
and eax, 0FFh
inc eax
mov bl, 160
mul bl
mov edi, eax
pop ebx
pop eax

ret
; DispReturn ??---------------------------------------------------------

SegCode32Len equ $ - LABEL_SEG_CODE32
; END of [SECTION .s32]


; 16 ?????. ? 32 ???????, ???????
[SECTION .s16code]
ALIGN 32
[BITS 16]
LABEL_SEG_CODE16:
; ?????:
mov ax, SelectorNormal
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax

mov eax, cr0
and al, 11111110b
mov cr0, eax

LABEL_GO_BACK_TO_REAL:
jmp 0:LABEL_REAL_ENTRY ; ??????????????????

Code16Len equ $ - LABEL_SEG_CODE16

; END of [SECTION .s16code]


; LDT
[SECTION .ldt]
ALIGN 32
LABEL_LDT:
;                            ???       ???      ??
LABEL_LDT_DESC_CODEA: Descriptor 0, CodeALen - 1, DA_C + DA_32 ; Code, 32 ?

LDTLen equ $ - LABEL_LDT

; LDT ???
SelectorLDTCodeA equ LABEL_LDT_DESC_CODEA - LABEL_LDT + SA_TIL
; END of [SECTION .ldt]


; CodeA (LDT, 32 ?????)
[SECTION .la]
ALIGN 32
[BITS 32]
LABEL_CODE_A:
mov ax, SelectorVideo
mov gs, ax ; ??????(??)

mov edi, (80 * 12 + 0) * 2 ; ??? 10 ?, ? 0 ??
mov ah, 0Ch ; 0000: ??    1100: ??
mov al, 'L'
mov [gs:edi], ax

; ????16??????????
jmp SelectorCode16:0
CodeALen equ $ - LABEL_CODE_A
; END of [SECTION .la]

Title: Re: A compile problem.
Post by: Frank Kotler on November 21, 2010, 03:37:23 PM
Mmmmm... 33050 vs 1078? Looks like excessive padding between sections(?). Looks like a bug! We'll look into it. Meanwhile, try another version. I'll get back to ya.

Thanks for the feedback!

Best,
Frank

Title: Re: A compile problem.
Post by: Frank Kotler on November 21, 2010, 04:22:22 PM
Oh my! Getting different sizes with every version I try! 2.08.01 looks like a good bet(?).  Latest snapshot (2.10rc2-20101108) does *not* seem to be right!

I'll see if I can come up with a simple test file that demonstrates the issue before I try to report the bug. "Help, Cyrill!"

Again, thanks for the feedback!

Best,
Frank

Title: Re: A compile problem.
Post by: Frank Kotler on November 21, 2010, 05:19:44 PM
If, instead of:

Code: [Select]
[section foo]
align 32

I do:

Code: [Select]
[section foo align=32]

throughout your file, I get a much smaller file (1146)... but not as small as the original assembled with 2.08.01 (1078). I think that's a "better"(?) way to specify section alignment, anyway. I'm getting more confused as I go along!

What size is it "supposed" to assemble to?

Best,
Frank

Title: Re: A compile problem.
Post by: cm on November 21, 2010, 05:48:59 PM
If, instead of:

Code: [Select]
[section foo]
align 32

I do:

Code: [Select]
[section foo align=32]

throughout your file, I get a much smaller file (1146)...

Of course, but (aside from any NASM bugs) the latter might not be what you want. Changing to the same section multiple times and using the stand-alone "align" multiple times after that, will align between every chunk that you write to that section. As opposed to specifying "align=" as section attribute; even with multiple such specifications (for multiple chunks) only one alignment will be applied. (The one in front of the section.)

Besides that, I didn't look much into the code yet. But what about using "sectalign off" (in case it is available) before any usage of "align"? Try whether that makes a difference.


Never mind, each section is only written to once in the provided code so neither comment applies. (Or, neither should. You can still play around with sectalign, see what changes with that.)
Title: Re: A compile problem.
Post by: Cyrill Gorcunov on November 21, 2010, 07:05:50 PM
Oh my! Getting different sizes with every version I try! 2.08.01 looks like a good bet(?).  Latest snapshot (2.10rc2-20101108) does *not* seem to be right!

I'll see if I can come up with a simple test file that demonstrates the issue before I try to report the bug. "Help, Cyrill!"

Again, thanks for the feedback!

Best,
Frank


I'll take a look what is going on there. It might be "smart"aligning issue or anything else.
Title: Re: A compile problem.
Post by: Frank Kotler on November 21, 2010, 07:33:26 PM
Yeah, "sectalign" seems better - still getting a difference between 2.09.03 and latest snapshot. "align=" as a property in the section declaration(s) still seems to work "better" for me.

Thanks for the help, guys!

Best,
Frank

Title: Re: A compile problem.
Post by: Cyrill Gorcunov on November 21, 2010, 07:38:35 PM
I'll take a look what is going on there. It might be "smart"aligning issue or anything else.

OK, it seems to be not a bug but a feature ;)

Look into http://www.nasm.us/xdoc/2.09.03/html/nasmdoc4.html#section-4.11.13
so if you need the ALIGN affect only PC (program counter) but not section, you have to turn off
section updater via SECTALIGN OFF directive.

Does it help?
Title: Re: A compile problem.
Post by: Frank Kotler on November 21, 2010, 08:05:45 PM
Wow, yeah "sectalign off" (added to the posted code) gives the smallest size yet - 1070 - and same with 2.09.03 and "latest snapshot". Not certain it's doing the "intended" thing. I still think that 30k+ file indicates a "bug", but maybe it's a "feature". (What's the "feature"?)

See if that's doing what you want, stanleylai.

Best,
Frank

Title: Re: A compile problem.
Post by: cm on November 21, 2010, 08:19:08 PM
Just for your information, assembling the posted example gets me this funny error unless I specify an output file name:

Code: [Select]
D:\>nasm pmtest3.asm
nasm: fatal: assertion addr <= s->start failed at output/outbin.c:1462

D:\>nasm pmtest3.asm -o pmtest3.com

D:\>nasm -v
NASM version 2.10rc1-20101106 compiled on Nov  6 2010

D:\>

The generated file (where I specified a name) contains 16730 bytes. This on a W32 machine as you might infer.
Title: Re: A compile problem.
Post by: Cyrill Gorcunov on November 21, 2010, 08:26:05 PM
Wow, yeah "sectalign off" (added to the posted code) gives the smallest size yet - 1070 - and same with 2.09.03 and "latest snapshot". Not certain it's doing the "intended" thing. I still think that 30k+ file indicates a "bug", but maybe it's a "feature". (What's the "feature"?)

See if that's doing what you want, stanleylai.

Best,
Frank


Since bin is a special target I guess we might need to set sectalign off for it by default.
Title: Re: A compile problem.
Post by: Cyrill Gorcunov on November 21, 2010, 08:26:37 PM
Just for your information, assembling the posted example gets me this funny error unless I specify an output file name:

Code: [Select]
D:\>nasm pmtest3.asm
nasm: fatal: assertion addr <= s->start failed at output/outbin.c:1462

D:\>nasm pmtest3.asm -o pmtest3.com

D:\>nasm -v
NASM version 2.10rc1-20101106 compiled on Nov  6 2010

D:\>

The generated file (where I specified a name) contains 16730 bytes. This on a W32 machine as you might infer.

Interesting, I'll take a look (in a couple of days probably). Thanks!
Title: Re: A compile problem.
Post by: cm on November 21, 2010, 08:32:16 PM
Some more hints: Specifying a list file but no output file does create the (default) output file. Specifying a list file and an output file triggers the assertion. Specifying a map file using the map directive always triggers the assertion, no matter the command line.
Title: Re: A compile problem.
Post by: Cyrill Gorcunov on November 21, 2010, 08:42:23 PM
ok, at moment it doesn't triggered on my computer. will investigate as only get spare time. Thanks for the hints, Christian!
Title: Re: A compile problem.
Post by: Frank Kotler on November 22, 2010, 01:53:27 AM
FWIW, I don't have any problem with not specifying an output file name, nor specifying a map file (funky old Linux, nasm-2.10rc2-20101108). That 16,730 bytes is still another different size!

Here's a potential "test" file:

Code: [Select]
[map]

; sectalign off ; <- this fixes it

; with no "org" - 70 bytes
; with this "org" - 459,286 bytes (!)
org 10000h

section A
align 32
nop

section B
align 32
nop
nop

section C
align 32
nop
nop
nop

section D
align 32
nop
nop
nop
nop

section E
align 32
nop
nop
nop
nop
nop

section F
align 32
nop
nop
nop
nop
nop
nop

Almost looks like the "org" is being added to the alignment padding every time we do it?

I'm not sure the "align 32"s are doing much to align the "nop"s in the best of cases, but are necessary to trigger the bug. Replacing them with "align=32" in the section declarations gives the result I presume is "intended" in the original code. With all the fuss about "align"s, he loads esp with 1FFh! No, no, no, ya want to keep the stack aligned to 4 bytes (at least!). Lose the "-1", or if you're nervous about that (it works fine), go with "-4".

Best,
Frank

Title: Re: A compile problem.
Post by: Cyrill Gorcunov on November 22, 2010, 03:37:45 PM
FWIW, I don't have any problem with not specifying an output file name, nor specifying a map file (funky old Linux, nasm-2.10rc2-20101108). That 16,730 bytes is still another different size!

Here's a potential "test" file:
...

Thanks a lot Frank for test-case! I'll try to take a look into it as soon as I can.
Title: Re: A compile problem.
Post by: stanleylai on November 27, 2010, 09:51:48 AM
Hi,

It's me again.

I compiled the source code with nasm-2.09.04. It still generated a large size.
Last time I didn't mention the size. It's not just large. It is huge.
It's over 1 GB.
My environment is the following:
OS is Windows vista.
CPU is Intel core 2 duo.
The DRAM is 4 GB.
Title: Re: A compile problem.
Post by: Frank Kotler on November 27, 2010, 06:54:37 PM
Holy ohmygoodness!!! Over 1 GB! I think that's the "best" yet!

Well... "align" is definitely broken (duh!). Besides exploding the file size, I don't think it's aligning stuff where you want. Replacing it with "align=32" (etc.) in the section declarations seems to work better. Here's the output with "[map]":

Code: [Select]
- NASM Map file ---------------------------------------------------------------

Source file:  pmtest3a.asm
Output file:  pmtest3a.com

-- Program origin -------------------------------------------------------------

00000100

-- Sections (summary) ---------------------------------------------------------

Vstart            Start             Stop              Length    Class     Name
             100               100               103  00000003  progbits  .text
             104               104               14A  00000046  progbits  .gdt
             160               160               196  00000036  progbits  .data1
             1A0               1A0               3A0  00000200  progbits  .gs
             3A0               3A0               4AA  0000010A  progbits  .s16
             4AC               4AC               50C  00000060  progbits  .s32
             520               520               53A  0000001A  progbits  .s16code
             540               540               548  00000008  progbits  .ldt
             560               560               57A  0000001A  progbits  .la

"[map all]" gives more info - might prove useful for debugging. By default, this spews to stdout - easily redirected. You can do "[map all pmtest3a.map]", too. Read all about it in the Friendly Manual.

Rather than (re)post your original code with the substitutions, I'll attach it. (I've been editing it in Linux - might have screwed up some line-endings - I think it's okay) See if it's producing what you had in mind...

Best,
Frank


Title: Re: A compile problem.
Post by: Keith Kanios on March 01, 2011, 04:00:26 PM
UPDATE: This particular ALIGN bug has been fixed as of 2.09.06/2.10rc4.

For specifics, read this nasm-devel list message (http://sourceforge.net/mailarchive/message.php?msg_id=27125803).