Hello all!

I am trying to complete a lab assignment for my computer systems class and we have to use the printf function to print changing register values (increment eax from 1 to 10, decrement ebx from 10 to 1).

Here is my code:

; Purpose: To print data to screen using printf
; Assemble: nasm -f elf -l printflab.lst printflab.asm
; Link: gcc -o printflab printflab.o


	extern printf		; The C function to be called

	section .data		; data section

fmt: db "eax=%d, ebx=%d", 10, 0 ; The printf format, "\n", '0'
	section .text		; code section

global main			; standard gcc entry point


main:				; program label for entry point

	mov ecx, 10		; set register ecx to value 10
	mov eax, 1		; set register eax to value 1	
	mov ebx, 10		; set register ebx to value 10 		

back1:				; loop label

	inc eax			; increment eax register
	dec ebx			; decrement ebx register
	push dword fmt		; address of ctrl string
	call printf		; Call C function
	loop back1		; loop until ecx = 0

endprog:			; exit the program

	mov esp, ebp		; takedown stack frame
	pop ebp			; same as "leave" op
	
	mov ebx, 0		; 0 = normal
	mov eax, 1		; 1 = no error
	int 0x80		; interrupt 80 hex, call kernel

After assembly and linking, the program just loops infinitely with the same number in both the eax and ebx registers. Am I missing something (like pushing the eax and ebx registers into the stack)?

Thanks in advance for your help

I recommend to push all necessary register before using external function. Add

push eax
push ebx
push ecx

before

call printf

and

pop ecx
pop ebx
pop eax

after it.

line 26: you are not pushing enough things before calling printf(). The format string you are using calls for two integers. You need to push those two integers as well as the format string.

Nothing seems to be working. I have tried doing as skaa said, but that did not help. It still loops infinitely... i know I am missing something, but I am new to assembly and we did not get to the printf section of our lecture in class.

EDIT:

Using GDB, I have found something weird, at least weird to me. When I single step through the back1 loop, the program comes to the printf call with all numbers correct. Single stepping into the printf function, control jumps to the function itself. This is normal, however, when the function is done, it single steps into something called ?? () from /lib/ld-linux.so.2. What is this and is it relevant? It will also not single step out of this weird function-like-thing, which is where the registers become corrupt and have wrong numbers stored in them.

1.I don't like this printf, i prefere use the library msvcrt.inc and use the crt_printf, remember that you need to push an offset not a DWORD..

2.You need to use 3 pushs in the printf because you need to move to the stack the first number, the second number and then the string...

3. I don't like to use this type of loop, i prefere the old CMP one, its just because it gets quicklier when the program is running

1.I don't like this printf, i prefere use the library msvcrt.inc and use the crt_printf, remember that you need to push an offset not a DWORD..

2.You need to use 3 pushs in the printf because you need to move to the stack the first number, the second number and then the string...

3. I don't like to use this type of loop, i prefere the old CMP one, its just because it gets quicklier when the program is running

#1: I have to use printf, that is what the assignment calls for.

#2: I tried pushing everything to the stack, it did not work.

#3: This is the only loop I know for NASM, as I have only been doing this for a few days

This was tested on VS C++ 2008:

char	fmt[]="eax=%d, ebx=%d\n";
_asm
{
	mov ecx, 8
	mov eax, 1
	mov ebx, 10

back1:
	inc eax
	dec ebx
	push	eax
	push	ebx
	push	ecx

	push	ebx
	push	eax
	lea	eax,fmt
	push	eax
	call dword ptr [printf]
	pop	eax
	pop	eax
	pop	eax

	pop	ecx
	pop	ebx
	pop	eax
	loop back1

	nop
}

. Working correctly.

What is the lea instruction? And how does that translate to NASM?

What is the lea instruction? And how does that translate to NASM?

there is no translation. It is a CPU mneumonic on x86 it means load effective address

You need to remove the calling parameter from the stack after the printf call

This:

push dword fmt ; address of ctrl string
call printf ; Call C function
loop back1 ; loop until ecx = 0

Should be:

push dword fmt ;address of ctrl string
call printf     ; Call C function
add esp, 4   ; remo
loop back1      ; loop until ecx = 0
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.