NASM - The Netwide Assembler
NASM Forum => Programming with NASM => Topic started 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 ????
-
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
-
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
-
Warning! Untested code!
%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...
-
Doggone! Push eax first, then fmt. Sorry/
Best,
Frank
-
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 ?
-
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
-
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.
-
For example:
How do you break a line with NASM for printing another string ?
-
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:
push fmt ; 4 bytes pushed.
push eax ; 4 bytes pushed.
call _printf
add esp, 8
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...).
-
How do you break a line with NASM for printing another string?
Print "\r\n" string to the console.
-
Sorry,
NASM seems to not recognize Print"\r\n"
-
Great,
I have understanded now for "add esp,8". Thanks
-
NASM seems to not recognize Print"\r\n"
Using Console API, assistech...
-
Great,
i used SASM, that's work....
I'm understand faster with you than book, thanks
-
Not tested, but maybe useful:
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):
$ 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...
-
Win32 code is a little bit different (different calling convention).
-
"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...
-
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:
db `\r\n`
And, of course, using '\', instead of '/'
-
Oops! Thank you Frederico!
Best,
Frank
-
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 ?
-
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:
$ gcc -O2 -masm=intel -S -mtune=native test.c
Take a look at test.s
-
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 ?
-
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...
-
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 ???
-
But my program don't work.... Why ???
Hummm... don't know... may because it is wrong?