Author Topic: Nasm is still quite stupid enough  (Read 2790 times)

Offline uncle Richard

  • Jr. Member
  • *
  • Posts: 8
Nasm is still quite stupid enough
« on: May 07, 2019, 07:42:06 AM »
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
//sites.google.com/site/excelmidi
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]
_start:
 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
 ret
[section .bss]
[common num 200]
[common AtMeTwo 4]
[common AtMeToo 4]
[common LookAtMe 4]
[extern printf]
[section .rdata]
@10:
 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: https://sites.google.com/site/excelmidi/file-sto/nasm.zip

Offline uncle Richard

  • Jr. Member
  • *
  • Posts: 8
Re: Nasm is still quite stupid enough
« Reply #1 on: May 10, 2019, 09:32:56 AM »
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.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2451
  • Country: us
Re: Nasm is still quite stupid enough
« Reply #2 on: May 10, 2019, 11:58:46 PM »
Hi uncle Richard,

Welcome to the forum.

I am terribly sorry you had trouble with Nasm.

Best,
Frank


Offline uncle Richard

  • Jr. Member
  • *
  • Posts: 8
Re: Nasm is still quite stupid enough
« Reply #3 on: April 20, 2020, 06:26:00 AM »
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
_start:
                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
                ret
.text   ends
.bss    segment
.bss    ends
        end

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.

Offline uncle Richard

  • Jr. Member
  • *
  • Posts: 8
Re: Nasm is still quite stupid enough
« Reply #4 on: April 21, 2020, 05:57:34 PM »
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]
@10:
   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

_start:
      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
      ret
.text   ends
.bss   segment
.bss   ends
   end

Understand why - don't even try! :) Anyway, try TCC as linker for Nasm. It's easy. Welcome Universal Student IDE https://sites.google.com/site/excelmidi/universal_student_ide/universal_student_ide_en for all compilers.

Offline uncle Richard

  • Jr. Member
  • *
  • Posts: 8
Re: Nasm is still quite stupid enough
« Reply #5 on: April 24, 2020, 02:54:21 PM »
Looking at the endless abundance of high-level languages, one might think that assembler has long died. But this is not so. Suppose you write a library and want to collect all the strings in one object file. Even using the lowest level of all the higher levels - C, nothing will work. All C compilers are the same in this respect. I have an answer why this is happening. But for now, I will refrain from discussing.

The simplest program and assembler for it.

#define STR1 ";string_1\r\n"
#define STR2 ";string_2\r\n"
#define STR3 ";string_3\r\n"
#define STR4 ";string_4\r\n"
#define STR5 ";string_5\r\n"
#define STR6 ";string_6\r\n"
extern int printf();
void _start (void){
   printf(STR1);
   printf(STR2);
   printf(STR5);
}

section code
[global   _start]
_start:
; Line 8:   void _start (void){

L_4:
; Line 9:      printf(STR1);

   push   dword L_1
   call   printf
   pop   ecx
; Line 10:      printf(STR2);

   push   dword L_2
   call   printf
   pop   ecx
; Line 11:      printf(STR5);

   push   dword L_3
   call   printf
   pop   ecx
; Line 12:   }

L_5:
   ret
section data
section code
section data
section string
L_3:
   db   ";string_5"
   db   0dh
   db   0ah
   db   00h
L_2:
   db   ";string_2"
   db   0dh
   db   0ah
   db   00h
L_1:
   db   ";string_1"
   db   0dh
   db   0ah
   db   00h
section const

section code
[extern   printf]


We have 6 strings, and only 3 are in the object file. Let's cut the program down to the can’t.

#define STR1 ";string_1\r\n"
#define STR2 ";string_2\r\n"
#define STR3 ";string_3\r\n"
#define STR4 ";string_4\r\n"
#define STR5 ";string_5\r\n"
#define STR6 ";string_6\r\n"

section code
section data
section code
section data
section const

The object file is full zero. And now we take the assembler and by the hands, hands :)

   SECTION .data
SECTION .data

STR1:
   db   ";string_1", 0dh, 0ah, 00h
STR2:
   db   ";string_2", 0dh, 0ah, 00h
STR3:
   db   ";string_3", 0dh, 0ah, 00h
STR4:
   db   ";string_4", 0dh, 0ah, 00h
STR5:
   db   ";string_5", 0dh, 0ah, 00h
STR6:
   db   ";string_6", 0dh, 0ah, 00h
;.....
« Last Edit: April 24, 2020, 07:16:34 PM by uncle Richard »

Offline uncle Richard

  • Jr. Member
  • *
  • Posts: 8
Re: Nasm is still quite stupid enough
« Reply #6 on: May 07, 2020, 08:28:36 PM »
Life goes on. And it is no secret that Nasm is still quite stupid enough. Now no dll from Nasm/Yasm elf output. Example.

//num_count_1.c
#define EOF (-1)
extern printf();
extern getchar();

_export void bb(void){
   int nc;
   for(nc=0;getchar()!=EOF;++nc);
   printf("%d\n", nc);   }
_export int __dllstart(){bb();
            return 0;}
++++++++++++++++++++++++++++++++++++++

nasm -f elf num_count_1.asm

   SECTION .text
   SECTION .data
   SECTION .bss
SECTION .text
[BITS 32]
[GLOBAL   bb]
bb:
;
; Line 7:   _export void bb(void){
;
   PUSH   EBP
   MOV   EBP,ESP
   SUB   ESP,BYTE 08H
L_3:
   MOV   DWORD [EBP-04H],00H
   JMP   SHORT   L_6
L_4:
;
; Line 9:   for(nc=0;getchar()!=EOF;++nc);
;
L_5:
   INC   DWORD [EBP-04H]
L_6:
   CALL   getchar
   CMP   EAX,BYTE 0FFFFFFFFH
   JNE   SHORT   L_4
L_7:
;
; Line 10:   printf("%d\n", nc);   }
;
   PUSH   DWORD [EBP-04H]
   PUSH   DWORD L_1
   CALL   printf
   ADD   ESP,BYTE 08H
L_2:
   MOV   ESP,EBP
   POP   EBP
   RET
[GLOBAL   __dllstart]
__dllstart:
;
; Line 11:   _export int __dllstart(){bb();
;
   PUSH   EBP
   MOV   EBP,ESP
L_9:
   CALL   bb
;
; Line 12:   return 0;}
;
   MOV   EAX,00H
L_8:
   POP   EBP
   RET
SECTION .data
L_1:
   DB   025H,064H,0AH,00H
SECTION .text
[BITS 32]

SECTION .text
[BITS 32]
   export __dllstart ; parser error
   export bb ; parser error
[EXTERN   getchar]
[EXTERN   printf]

Got parser error & parser error. Maybe elf format have no exports in Windows? Have! Tcc prove it well. Let me guess. Frank Kotler again will say - I am terribly sorry you had trouble with Nasm. O, thank you Frank.:) Longing is green. Black dog. Dumps.

Offline uncle Richard

  • Jr. Member
  • *
  • Posts: 8
Re: Nasm is still quite stupid enough
« Reply #7 on: May 08, 2020, 08:37:51 PM »
Day two. The weather was bad. The princess was wet. I love wet princesses very much. And you? :) Here is a small dump from the previous listing. newdll.o

00000000  7F 45 4C 46 01 01 01 00-00 00 00 00 00 00 00 00  .ELF............
00000010  01 00 03 00 01 00 00 00-00 00 00 00 00 00 00 00  ................
00000020  40 00 00 00 00 00 00 00-34 00 00 00 00 00 28 00  @.......4.....(.
00000030  08 00 04 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000040  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000050  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000060  00 00 00 00 00 00 00 00-01 00 00 00 01 00 00 00  ................
00000070  06 00 00 00 00 00 00 00-80 01 00 00 1C 00 00 00  ................
00000080  00 00 00 00 00 00 00 00-10 00 00 00 00 00 00 00  ................
00000090  07 00 00 00 01 00 00 00-03 00 00 00 00 00 00 00  ................
000000A0  A0 01 00 00 09 00 00 00-00 00 00 00 00 00 00 00  ................
000000B0  04 00 00 00 00 00 00 00-0D 00 00 00 08 00 00 00  ................
000000C0  03 00 00 00 00 00 00 00-B0 01 00 00 04 00 00 00  ................
000000D0  00 00 00 00 00 00 00 00-04 00 00 00 00 00 00 00  ................
000000E0  12 00 00 00 03 00 00 00-00 00 00 00 00 00 00 00  ................
000000F0  B0 01 00 00 36 00 00 00-00 00 00 00 00 00 00 00  ....6...........
00000100  01 00 00 00 00 00 00 00-1C 00 00 00 02 00 00 00  ................
00000110  00 00 00 00 00 00 00 00-F0 01 00 00 B0 00 00 00  ................
00000120  06 00 00 00 08 00 00 00-04 00 00 00 10 00 00 00  ................
00000130  24 00 00 00 03 00 00 00-00 00 00 00 00 00 00 00  $...............
00000140  A0 02 00 00 51 00 00 00-00 00 00 00 00 00 00 00  ....Q...........
00000150  01 00 00 00 00 00 00 00-2C 00 00 00 09 00 00 00  ........,.......
00000160  00 00 00 00 00 00 00 00-00 03 00 00 18 00 00 00  ................
00000170  05 00 00 00 01 00 00 00-04 00 00 00 08 00 00 00  ................
00000180  55 89 E5 6A 40 68 00 00-00 00 FF 35 00 00 00 00  U..j@h.....5....
00000190  6A 00 E8 FC FF FF FF 83-C4 10 5D C3 00 00 00 00  j.........].....
000001A0  46 72 6F 6D 20 44 4C 4C-00 00 00 00 00 00 00 00  From DLL........
000001B0  00 2E 74 65 78 74 00 2E-64 61 74 61 00 2E 62 73  ..text..data..bs
000001C0  73 00 2E 73 68 73 74 72-74 61 62 00 2E 73 79 6D  s..shstrtab..sym
000001D0  74 61 62 00 2E 73 74 72-74 61 62 00 2E 72 65 6C  tab..strtab..rel
000001E0  2E 74 65 78 74 00 00 00-00 00 00 00 00 00 00 00  .text...........
000001F0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000200  01 00 00 00 00 00 00 00-00 00 00 00 04 00 F1 FF  ................
00000210  00 00 00 00 00 00 00 00-00 00 00 00 03 00 01 00  ................
00000220  00 00 00 00 00 00 00 00-00 00 00 00 03 00 02 00  ................
00000230  00 00 00 00 00 00 00 00-00 00 00 00 03 00 03 00  ................
00000240  2E 00 00 00 03 00 00 00-00 00 00 00 00 00 01 00  ................
00000250  32 00 00 00 1A 00 00 00-00 00 00 00 00 00 01 00  2...............
00000260  36 00 00 00 00 00 00 00-00 00 00 00 00 00 02 00  6...............
00000270  23 00 00 00 00 00 00 00-00 00 00 00 10 00 01 00  #...............
00000280  3A 00 00 00 00 00 00 00-00 00 00 00 10 00 03 00  :...............
00000290  45 00 00 00 00 00 00 00-00 00 00 00 10 00 00 00  E...............
000002A0  00 45 3A 5C 00 00 00 00-00 00 00 00 00 00 00 00  .E:\............
000002B0  00 00 00 00 00 00 00 5C-6E 65 77 64 6C 6C 2E 41  .......\newdll.A
000002C0  53 4D 00 68 65 6C 6C 6F-5F 66 75 6E 63 00 4C 5F  SM.hello_func.L_
000002D0  33 00 4C 5F 32 00 4C 5F-31 00 68 65 6C 6C 6F 5F  3.L_2.L_1.hello_
000002E0  64 61 74 61 00 4D 65 73-73 61 67 65 42 6F 78 41  data.MessageBoxA
000002F0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000300  06 00 00 00 01 03 00 00-0C 00 00 00 01 04 00 00  ................
00000310  13 00 00 00 02 0A 00 00-00 00 00 00 00 00 00 00  ................

I made it by hand.:) Therefore, there may be small errors. But I tried and was extremely attentive.:) It is enough to change some bytes and Tcc will accept this file for execution to DLL. If you managed correctly, a def file should appear. newdll.def - LIBRARY newdll.dll EXPORTS hello_data hello_func  Successes.:) I am terribly sorry you had trouble with me, Frank.:)