0 Replies - 1524 Views - Last Post: 24 April 2009 - 01:27 PM

#1 NickDMax   User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2255
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Windows Console Print

Posted 24 April 2009 - 01:27 PM

Description: Uses the stdcall calling convention so you can call from C by declaring as 'extern _stdcall _consoleOutput(char *);'. In assembly push a pointer to a zero terminated message and call. No need to clean up the stack afterward.Display a line of text directly to the windows console.
.386p
PUBLIC _asmMain, _consoleOutput, _strLen
EXTERN WriteConsoleA	:near
EXTERN GetStdHandle		:near

STD_OUTPUT_HANDLE 	EQU -11

MODEL flat, C
_TEXT	segment dword public use32 'CODE'

; A windows console print routine. This uses the (windows) stdcall calling convention and will return a value
; indicating the number of characters written. -- This is a wrapper for the windows WriteConsoleA function
_consoleOutput proc near   	; _stdcall int consoleOutput(char *cstring);                  
	push 	ebp                            
	mov 	ebp, esp		; set base pointer to stack pointer
	add 	esp, -4			;Set aside some room for our local variable (#chars written).
	push 	ebx
	
	; we want to make a call to:
	; WriteConsoleA(int ConsoleHandle, char * string, int length, int *numCharsWritten, NULL);
	; but we will need to calculate the length, and we need to call GetStdHandle(int STD_OUTPUT_HANDLE) 
	; to get the handle. So in C the line of code would be:
	; WriteConsoleA(GetStdHandle(int STD_OUTPUT_HANDLE), &string, _strLen(&string), &count, NULL);
	; 
	; Our calling convention pushes arguments in from last to first (so they are pop'ed first to last).
	; so first we need to push NULL (0).
	
	push 	0

	; Next we want to push the pointer to our local variable (# of chars written).
	lea 	edx, dword ptr [ebp-4] ; push a pointer to local stack variable...
	push 	edx

	; Now we take a little side track to calculate the length of the string...
	mov		ebx, dword ptr [ebp+8]	; ebx == pointer to string..
	
	; push the pointer to the string
	push	ebx
	call	_strLen
	push	eax		; now push the result
	
	push	ebx		; push the pointer to the string...
	
	push 	STD_OUTPUT_HANDLE	; push -11 -- argument to GetStdhandle
	call 	GetStdHandle
	; no need to clean up the stack since windows uses the pascal calling convention (where the callee cleans the stack).
	push	eax
	
	call	WriteConsoleA
	; Again no need to clean up the stack since windows uses the pascal calling convention.
	mov 	eax, [ebp-4]	;load the return value into eax
	
	pop 	ebx
	mov 	esp, ebp
    pop 	ebp
    ret		4
_consoleOutput 	endp

;A routine used to calculate the length of a string. This is already as snippet though using the C calling convention.
_strLen proc near   ; _stdcall int strLen(char *str)
	push 	ebp                            
	mov 	ebp, esp                      
	push 	edi
	push	ecx
	pushf
	mov 	edi, dword ptr [ebp+8]	; get our pointer from the stack
	xor 	ecx, ecx	;zero ecx
	not 	ecx			;set ecx to the max integer 0xFFFF FFFF
	xor 	al, al		;zero  al
	cld 				;clear the direction flag so we move along the string forwards
	repne	scasb		;scan string byte for byte [di] == al
	not 	ecx
	dec 	ecx
	mov 	eax, ecx	;set our return value...
	popf
	pop 	ecx
	pop 	edi
	pop 	ebp
	ret 	4
_strLen 	endp

_TEXT    ends

END



Is This A Good Question/Topic? 0
  • +

Page 1 of 1