NASM - The Netwide Assembler

NASM Forum => Programming with NASM => Topic started by: assistech on April 13, 2020, 12:23:57 PM

Title: Display result
Post by: assistech on April 13, 2020, 12:23:57 PM
Hi,


I'm programming a simple program and running Windows 10 or 7, i would like to display the result of my operation on CMD after to execute it. This is my program:


global _main:

section .text
          extern printf

_main:

     mov eax,10000h
     add eax,40000h
     sub eax,20000h
 
     push eax
     call printf



What is wrong ????
Title: Re: Display result
Post by: Frank Kotler on April 14, 2020, 12:45:44 AM
Hi assistech.

Welcome to the forum.

You don't say what's wrong. I don't do Windows. Wild asm guess:

You need to spell "_printf" with a leading underscore.
You need a format string.
You need to clean up stack and "ret".

Hope that helps.

Best,
Frank

Title: Re: Display result
Post by: assistech on April 15, 2020, 12:53:17 AM
Ok, if i write this complete code from SASM editor, could you correct or add instruction for display EAX result for me please:


%include "io.inc"

section .data

section .text

      global CMAIN

CMAIN:
      mov ebp,esp  ;for correct debugging
      NEWLINE

      mov eax,10h
      mov eax, 40h
      sub eax,20h

      xor eax,eax

      ret


Where could put "_printf" ?


Thanks

Title: Re: Display result
Post by: Frank Kotler on April 15, 2020, 02:14:52 AM
Warning! Untested code!

Code: [Select]
%include "io.inc"

extern _printf

section .data

    fmt db "result is %d", 10, 0

section .text

      global CMAIN

CMAIN:
      mov ebp,esp  ;for correct debugging
      NEWLINE

      mov eax,10h
      mov eax, 40h
      sub eax,20h

    push fmt
    push eax
    call _printf
    add esp, 8

      xor eax,eax

      ret

Doggone it! Where do I find "io.inc'? Well, SASM I guess...
Something like that...

Doggone it! Someone doing 'doze help this guy!

Best,
Frank

P.S. "code" in square brackets, "/code" in square brackets...

Title: Re: Display result
Post by: Frank Kotler on April 15, 2020, 03:30:31 AM
Doggone! Push eax first, then fmt. Sorry/

Best,
Frank


Title: Re: Display result
Post by: assistech on April 15, 2020, 11:32:00 AM
Great, Great, Great......


It's seem that is instruction "add esp,8" which allow to display on the screen the result!!!!

Can you explain me why ? What is ESP ?
Title: Re: Display result
Post by: Frank Kotler on April 15, 2020, 09:30:22 PM
Hi assistech,

ESP is the (32 bit) stack pointer. The stack is an area of memory set aside for the push and pop instructions. It works from high memory to low. It is a;so used by the call instruction to srore the address to return to when the call returns. When the "ret" instruction occurs, it takes the first thing on the stack (upwards) and goes there. In this case, the "C startup code" (which we don't see) calls _main. When our code returns, it exits cleanly back to the OS. We push eax and the address of "fmt" onto the stack (below the return address). These parameters have to be removed for our code to return to its caller. C functions do not remove their parameters... but Windows APIs do. Are you confused yet? You need a good book, and I really don't know what to recommend. Maybe Jeff Duntemann?

Best,
Frank

Title: Re: Display result
Post by: assistech on April 18, 2020, 12:19:04 PM
Ok, i'm understand:


1- But why the value "8" inside instruction "add esp,8", why not "16" or "24" ?

2- I have ever old book about Assembly like MASM which uses this for display registers: "call DumpRegs".

3- The problem is after looking for everywhere (books, article,website,...) response about display registers, n o one give explainations about it except you or MASM with call DumpRegs. Nasm doc don't talk about it "add esp,8", how can i know ? That's why i had abandon Assembly langage

4- But i will looking for Jeff Duntemann books later.
Title: Re: Display result
Post by: assistech on April 18, 2020, 02:56:19 PM
For example:


How do you break a line with NASM for printing another string ?
Title: Re: Display result
Post by: fredericopissarra on April 18, 2020, 04:02:15 PM
1- But why the value "8" inside instruction "add esp,8", why not "16" or "24" ?
Because, previously, you pushed 8 bytes on the stack:
Code: [Select]
  push fmt    ; 4 bytes pushed.
  push eax    ; 4 bytes pushed.
  call _printf
  add esp, 8

Quote from: assistech
2- I have ever old book about Assembly like MASM which uses this for display registers: "call DumpRegs".

3- The problem is after looking for everywhere (books, article,website,...) response about display registers, n o one give explainations about it except you or MASM with call DumpRegs. Nasm doc don't talk about it "add esp,8", how can i know ? That's why i had abandon Assembly langage

4- But i will looking for Jeff Duntemann books later.
The problem with old books about x86 assembly is that their examples are outdated and, probably, using a custumized library. On Win32/Win64 you must use Console API (https://docs.microsoft.com/en-us/windows/console/console-functions) functions like GetStdHandle() and WriteConsole() and to exit your program, ExitProcess() Win API function.

Windows 10 has no support whatsoever to old MS-DOS console apps.

You'll have to do some work to import the Win API functions to your console app. So, I don't recomment to write entire programs in assembly, since a C/C++ compiler will do this work for you.

Ahhh... and, nowadays, I recommend you try to use x86-64 mode, not the old i386 (32 bits) mode... Almost everyone is using 64 bits mode now (different calling convention, some different rules to register usage, more registers available, etc...).
Title: Re: Display result
Post by: fredericopissarra on April 18, 2020, 04:06:20 PM
How do you break a line with NASM for printing another string?

Print "\r\n" string to the console.
Title: Re: Display result
Post by: assistech on April 18, 2020, 05:39:51 PM

Sorry,

NASM seems to not recognize Print"\r\n"
Title: Re: Display result
Post by: assistech on April 18, 2020, 06:02:04 PM
Great,


I have understanded now for "add esp,8". Thanks
Title: Re: Display result
Post by: fredericopissarra on April 18, 2020, 06:21:01 PM
NASM seems to not recognize Print"\r\n"
Using Console API, assistech...
Title: Re: Display result
Post by: assistech on April 18, 2020, 07:16:04 PM
Great,

i used SASM, that's work....


I'm understand faster with you than book,  thanks
Title: Re: Display result
Post by: fredericopissarra on April 18, 2020, 07:26:39 PM
Not tested, but maybe useful:
Code: [Select]
bits 64
default rel

section .rodata

hextable:
  db  "0123456789ABCDEF"

section .text

; From Windows API.
; You'll need to link with the corresponding static library for those (kernel32.lib?).
extern __imp_GetStdHandle
extern __imp_WriteConsoleA
extern __imp_ExitProcess

; Convert ECX to string pointed by RDX.
cvt2hex:
  mov r9d,ecx                        ; save ecx.
  mov ecx,28                         ; we'll start left shifting 28 bits.
.loop:
  mov   eax,r9d                      ; restore value to eax.

  shr   eax,cl                       ; isolate the corresponding nibble in LSB.
  and   eax,0x0f

  sub   ecx,4                        ; next time, left shift 4 bits less.

  movzx eax,byte [hextable+rax]      ; gets the hex digit...
  mov   [rdx],al                     ; ... and store in the buffer.

  add   rdx,1                        ; advance buffer position.

  test  ecx,ecx
  jns  .loop                         ; continue in the loop if ECX isn't negative.
  ret

; Print EDX chars from the buffer pointed by RCX.
Print:
  push  rsi
  push  rbx

  sub   rsp,8                        ; Allocate space for WriteConsoleA last argument.

  mov   esi,edx                      ; save EDX and RCX.
  mov   rbx,rcx                       

  mov   ecx,-11                      ; -11 is STD_OUTPUT_HANDLE constant (console api).
  call  qword [__imp_GetStdHandle]
  ; Here EAX contains the STD_OUTPUT_HANDLE console handle.

  xor   r9d,r9d                      ; num chars writen pointer is NULL.
  mov   r8d,esi                      ; num chars to write.
  mov   rdx,rbx                      ; pointer to char buffer.
  mov   qword [rsp],0                ; last argument is NULL.
  mov   rcx,rax                      ; console handle.
  call  qword [__imp_WriteConsoleA]

  add   rsp,8                        ; Deallocate space allocated on stack.

  pop   rbx
  pop   rsi
  ret

; Display ECX on console, in hexadecimal.
display:
  sub rsp,8               ; Allocate buffer of 8 chars.

  ; Convert ECX to string.
  mov r10,rsp
  mov rdx,rsp
  call  cvt2hex

  ; Print the string.
  mov edx,8
  mov rcx,r10
  call  Print

  add rsp,8               ; Deallocate the buffer.
  ret

  global  _start
_start:
  mov   ecx,0xDEADBEEF
  call  display

  ; Put the rest of your code here...

  xor   ecx,ecx
  jmp   qword [__imp_ExitProcess]

  ; Never gets here!

On Linux, with MinG64 installed, this should work (not tested):

Code: [Select]
$ nasm -fwin64 -o test.o test.asm
$ x86_64-w64-mingw32-ld -o test.exe test.o -e_start -L /usr/x86_64-w64-mingw32/lib -l:libkernel32.a

I leave to you to discover how to link this with microsoft linker...
Title: Re: Display result
Post by: fredericopissarra on April 18, 2020, 07:29:01 PM
Win32 code is a little bit different (different calling convention).
Title: Re: Display result
Post by: Frank Kotler on April 18, 2020, 09:46:56 PM
"r" = carriage return = 13 (0xd)
"n" = linefeed = 10 (0xa)

db "my string", 13, 10, 0

Best,
Frank

P.S. With "back quotes" Nasm may recognize
db /n/r
Curses! Why can't I print "back quotes" aka "back aposrtrophes'? Over the TAB key...

Title: Re: Display result
Post by: fredericopissarra on April 19, 2020, 11:14:03 AM
P.S. With "back quotes" Nasm may recognize

db /n/r

Curses! Why can't I print "back quotes" aka "back aposrtrophes'? Over the TAB key...

Try to use code tags:
Code: [Select]
db `\r\n`
And, of course, using '\', instead of '/'
Title: Re: Display result
Post by: Frank Kotler on April 19, 2020, 08:12:34 PM
Oops! Thank you Frederico!

Best,
Frank

Title: Re: Display result
Post by: assistech on April 20, 2020, 10:36:41 AM
Hi,


I would like to clear my screen with console API from this page: https://docs.microsoft.com/en-us/windows/console/clearing-the-screen


How can i integrate or call it in my NASM program ?
Title: Re: Display result
Post by: fredericopissarra on April 20, 2020, 11:02:23 AM
I would like to clear my screen with console API from this page: https://docs.microsoft.com/en-us/windows/console/clearing-the-screen

See what the compiler does:
Code: [Select]
$ gcc -O2 -masm=intel -S -mtune=native test.cTake a look at test.s
Title: Re: Display result
Post by: assistech on April 20, 2020, 11:13:13 PM
Hi,


I am so sorry, i am suck at assembly, where can i find "test.s" ????



Can you add instruction on my program to show me how i can clear my screen with API windows ?






Title: Re: Display result
Post by: fredericopissarra on April 21, 2020, 12:00:54 AM
I am so sorry, i am suck at assembly, where can i find "test.s" ????
Write the code in C, compile with gcc using -S option and get the .s file (assembly listing)... Add -masm=intel option if you want Intel mnemonics.

I'll not do your work for you...
Title: Re: Display result
Post by: assistech on April 21, 2020, 12:04:10 PM
Great,


I used " gcc -S -masm=intel clearscreen.c" and i have obtain clearscreen.s file. Now i have "cls" in C converted to asm.

But my program don't work.... Why ???


 
Title: Re: Display result
Post by: fredericopissarra on April 21, 2020, 07:29:12 PM
But my program don't work.... Why ???
Hummm... don't know... may because it is wrong?