NASM Forum > Summer of Code Ideas

Nasm is still quite stupid enough

(1/2) > >>

uncle Richard:
Not so long ago, Nasm (version 0.98.38 compiled on Mar 5 2011) could not correctly count near jumps. Now, uninitialized variables still stink, too. Here is a simple program:

//no.c (c) Tereshkov_OE
extern void printf (const char *_Format,...);
int  LookAtMe, AtMeToo, AtMeTwo;
int  num[50];

void _start(void)
LookAtMe=67; AtMeToo=45; AtMeTwo=29;
LookAtMe = LookAtMe+AtMeToo+AtMeTwo;
printf(" %d\n", LookAtMe);

Take Pelles C 8.0 and get:

[global _start]
[section .text]
 push ebp
 mov ebp,esp
 sub esp,4
 mov dword [(LookAtMe)],67
 mov dword [(AtMeToo)],45
 mov dword [(AtMeTwo)],29

 mov eax,dword [(LookAtMe)]
 add eax,dword [(AtMeToo)]

 mov dword [ebp+(-4)],eax ;stupidity

 add eax,dword [(AtMeTwo)]
 mov dword [(LookAtMe)],eax

 push dword [(LookAtMe)]
 push dword (@10)
 call printf
 add esp,(8+3)&(~3) ;double stupidity

 mov esp,ebp
 pop ebp
[section .bss]
[common num 200]
[common AtMeTwo 4]
[common AtMeToo 4]
[common LookAtMe 4]
[extern printf]
[section .rdata]
 db ' %d',10,0
[cpu pentium]

Nasm (version 2.14.02 compiled on Dec 26 2018) like compiler. Tcc as linker. Run the program. Result 87. From which it follows that nobody uses Nasm under Windows32, including the authors. PureBasic 3.20 was try to use Nasm and then went to Fasm. Why?

The same program for PCC&Yasm like compiler and TCC as linker brings 141. Archive:

uncle Richard:
Three days have passed. But H. Peter Anvin, Cyrill Gorcunov, Chang Seok Bae, Jim Kukunas, Frank B. Kotler are silent. So. The main problem with Nasm is that it does not have a linker. And if it is not needed in Linux, in Windows it is absolutely necessary. TCC is a C compiler and a satisfactory linker for the elf format, simultaneously. But no one can guarantee on how correct this TCC is.

A bunch of Gcc+Yasm+TCC brings a result of 87, too. Thus, Gcc and TCC can be defective, and Nasm can be normal. The earlier Nasm will acquire its own linker and IDE, the better. Fasm popularity is the best proof of this.

It should be only one regret. MSVC, GCC, TCC, DmC, Pelle C, PCC, NASM, FASM, YASM, GOASM, UASM, MASM are excellent compilers, each in its own way. And this is good. The bad thing is that they are completely incompatible with each other. Even at the 'Hello World' level. And they will not.

Pelle C is closest to me. I wrote a small converter Pelle -> NASM + TCC. Everything works, except comm variables. Even Agner Fog does not know what to do with them.

Frank Kotler:
Hi uncle Richard,

Welcome to the forum.

I am terribly sorry you had trouble with Nasm.


uncle Richard:
A year has passed. All the sages, who wanted or could have, already spoken out. It's time to put dot in the end. Let's look inside the finished program.

Section .text

* Entry Point:

00401000: 55                   push ebp
00401001: 89E5                 mov ebp, esp
00401003: 81EC04000000         sub esp, 00000004
00401009: C7054C20400043000000 mov dword ptr [0040204C], 00000043
00401013: C7054C2040002D000000 mov dword ptr [0040204C], 0000002D
0040101D: C7054C2040001D000000 mov dword ptr [0040204C], 0000001D
00401027: A14C204000           mov eax, [0040204C]
0040102C: 03054C204000         add eax, [0040204C]
00401032: 8945FC               mov [ebp-04], eax
00401035: 03054C204000         add eax, [0040204C]
0040103B: A34C204000           mov [0040204C], eax
00401040: FF354C204000         push dword ptr [0040204C]
00401046: 6800304000           push 00403000
0040104B: E810000000           call msvcrt.printf
00401050: 81C408000000         add esp, 00000008
00401056: 89EC                 mov esp, ebp
00401058: 5D                   pop ebp
00401059: C3                   ret

Maybe this is all insidious TCC? Take a look at the object file.

        public  _start
        comm    num:byte:0c8h
        comm    AtMeTwo:byte:04h
        comm    AtMeToo:byte:04h
        comm    LookAtMe:byte:04h
        extrn   printf

.text   segment
                push    EBP
                mov     EBP,ESP
                sub     ESP,4
                mov     dword ptr @SYM32[00h],043h
                mov     dword ptr @SYM32[00h],02Dh
                mov     dword ptr @SYM32[00h],01Dh
                mov     EAX,@SYM32[00h]
                add     EAX,@SYM32[00h]
                mov     -4[EBP],EAX
                add     EAX,@SYM32[00h]
                mov     @SYM32[00h],EAX
                push    dword ptr @SYM32[00h]
                push    offset FLAT:@10[047h]@SYM32
                call      printf@PC32
                add     ESP,8
                mov     ESP,EBP
                pop     EBP
.text   ends
.bss    segment
.bss    ends

No, not TCC. This is NASM/YASM such. TCC is a great linker and compiler. But, as it turned out, it had nothing to link except itself. Of course, one can make assumptions about the role of "mov dword [ebp + (- 4)], eax", which is completely unnecessary and which PelleC so shamelessly generates. But the fact remains that only very brave and reckless programmers, like you, can use NASM/YASM. :) And who just came up with these not initialized global variables?! Agner Fog will confirm.

uncle Richard:
Day two. The weather was great. The princess was bad. :) As often happens in such cases, the solution to the problem turned out to be very simple:

[section .bss]
[common num 200:4]
[common AtMeTwo 4:4]
[common AtMeToo 4:4]
[common LookAtMe 4:4]
[extern printf]
[section .rdata]
   db ' %d',10,0

Those who play AT&T with Yasm:

   .comm LookAtMe,04,4
   .comm AtMeToo,04,4
   .comm AtMeTwo,04,4
   .comm num,0310,4
Why int  num[50]; >>> .comm num,0310,4 in pcc 1.1.0 for win32? Who Knows?:)
pcc is not only :) GCC:

.comm LookAtMe,16
.comm AtMeToo,16
.comm AtMeTwo,16
.comm num,208

The Nasm object file looks exactly the same, but now it works:

   public   _start
   comm   num:byte:0c8h
   comm   AtMeTwo:byte:04h
   comm   AtMeToo:byte:04h
   comm   LookAtMe:byte:04h
   extrn   printf
.text   segment

      push   EBP
      mov   EBP,ESP
      sub   ESP,4
      mov   dword ptr @SYM32[00h],043h
      mov   dword ptr @SYM32[00h],02Dh
      mov   dword ptr @SYM32[00h],01Dh
      mov   EAX,@SYM32[00h]
      add   EAX,@SYM32[00h]
      add   EAX,@SYM32[00h]
      mov   @SYM32[00h],EAX
      push   dword ptr @SYM32[00h]
      push   offset FLAT:@10[041h]@SYM32
      call     printf@PC32
      add   ESP,8
      mov   ESP,EBP
      pop   EBP
.text   ends
.bss   segment
.bss   ends

Understand why - don't even try! :) Anyway, try TCC as linker for Nasm. It's easy. Welcome Universal Student IDE for all compilers.


[0] Message Index

[#] Next page

Go to full version