I am doing Narue's Introduction to Assembly, and when I run my program, nothing happens.

This is my code:

[section .data]
	hello: db 'Hello, world!', 10, 0 ;15 bytes
	nl:    db ' ', 10, 0 ;3 bytes

[section .text]
	global _main, _print_nl, _print_msg, _return
	extern _printf

_print_nl:
	push	nl
	call    _printf
	add     esp, 4

_print_msg:
	push    hello
	call    _printf
	add     esp, 4

_return:
	mov     eax, 0
	ret

_main:
	call	_print_msg	
	call	_print_nl
	call    _print_msg

	call    _return

This is what happened in my command window:

C:\Documents and Settings\tom\Desktop\Assembly>nasm -f win32 First.asm -o First.obj
C:\Documents and Settings\tom\Desktop\Assembly>gcc First.obj -o prog.exe
C:\Documents and Settings\tom\Desktop\Assembly>prog.exe
C:\Documents and Settings\tom\Desktop\Assembly>

Any help would be appreciated

Recommended Answers

All 16 Replies

Can someone please help me?

MASM is my thing when linked with Visual Studio. Not NASM but I'll try to help...

Assemble First.asm into an Win32 object file First.obj
C:\Documents and Settings\tom\Desktop\Assembly>nasm -f win32 First.asm -o First.obj
Seems okay
C:\Documents and Settings\tom\Desktop\Assembly>gcc First.obj -o prog.exe


C:\Documents and Settings\tom\Desktop\Assembly>prog.exe
C:\Documents and Settings\tom\Desktop\Assembly>

Try moving the .data section below the .text (code) section. If the data is put into the code segment then the code is being displaced and the data is being treated as code. Dumping lst output or memory map would give more clues!

In masm one would define
end Start
at the end of the file to indicate where the code is to start. As the concept of 'main' is a C/C++ thing, not assembly language! It merely starts at the beginning of the code segment unless overwritten like with the end Main as indicated!

Looking at the NASM documentation, it appears you need to insert a declaration.

.start
_main:

So the code knows where to begin execution!

This is now my code:

[section .bss ]
	name: resb 64

[section .start]
		global _main, _print_nl, _print_msg, _return
		extern _printf, _read
	_main:	
		push    msg
		call    _printf
		call    _read
		
		push    hello
		call    _printf
		
		push eax
		call    _printf
		
		push    exmrk
		call    _printf
		
		push	nl
		call    _printf
		
		add     esp, 20
		
		mov     eax, 0
		ret

[section .data]
	msg:   db 'Enter your name: ',0;18 bytes
	hello: db 'Hello, ', 0 ;9 bytes
	nl:    db ' ', 10, 0 ;3 bytes
	exmrk: db '!',0 ;2 bytes

_read DOES get input from the user and store it in eax right?

This is what happens when I run the thing:

Exiting due to signal SIGSEGV
Stack Fault at eip=00088a87
eax=00000001 ebx=00000299 ecx=00000001 edx=0000033f esi=00000054 edi=0000fd7c
ebp=0008fd70 esp=0008fd5c program=C:\DOCUME~1\TOM\DESKTOP\ASSEMBLY\FIRST.EXE
cs: sel=01a7  base=02990000  limit=0009ffff
ds: sel=01af  base=02990000  limit=0009ffff
es: sel=01af  base=02990000  limit=0009ffff
fs: sel=017f  base=00005a80  limit=0000ffff
gs: sel=01bf  base=00000000  limit=0010ffff
ss: sel=01af  base=02990000  limit=0009ffff
App stack: [0008fd7c..0000fd7c]  Exceptn stack: [0000fcdc..0000dd9c]

Call frame traceback EIPs:
  0x00088a87

help?

ok, sorry, here is my code again that still doesn't work:

[section .data ]
	hello: db 'Hello, world!',10,0

[section .text ]
	global _main
	extern _printf
        .start
_main:
	push hello
	call _printf
	add esp,4

	mov eax,0
	ret

it doesn't do anything when i run it :(
any help?

For every push before a call, you have to adjust the stack.

You can't be throwing around code changes and hope it works. You had the code reasonable before. If you're going to make massive changes like that you need to indicate the changes worked, and then why you throwing away what you were helped with.

Which gcc port are you using? If it is cygwin, then that might be your problem.

Try MingW -- I've always had success with it.

http://www.mingw.org/

Assember is a two pass. If that doesn't work, move all the data in the .data section below the code in the .text section. In these simple configurations typically the Code Segment and Data Segment are shared and having data at the top of your code makes the data appear like opcodes (thus instructions) to the processor and it trys to run the data like code!

When you run it! So that would indicate you get a clean assemble and link and thus you are successful in linking to the libary that contains the print code.

Assember is a two pass. If that doesn't work, move all the data in the .data section below the code in the .text section. In these simple configurations typically the Code Segment and Data Segment are shared and having data at the top of your code makes the data appear like opcodes (thus instructions) to the processor and it trys to run the data like code!

No, wildgoose. What you are saying simply can not happen.

The sections are separated in the object file. The linker may even choose to re-order them when it creates the executable file. The Operating System's loader will likely scatter them into widely-separated areas of memory. In general, the order of .data and .text sections has no effect. The code will start executing at the '_main' label no matter where it appears within the .text section.

However, in a Linux environment, on certain old kernel versions, the order DOES matter. A '.data' section is expected as the last section due to security device implemented by that kernel.

wildgoose -

What you are thinking of is the old '*.com' and '*.exe' formats for DOS which had a segmented memory model. Yes, the '*.com' files were restricted to the SMALL data model which combined all four segments into one -- so the author *did* have to be careful where he place data.

However, modern 32-bit code for modern 32-bit Operating System's do not have support for segments because they all use Virtual Memory.

Almost all of these beginners are using 16-bit REAL Mode versions of the assembler. Very few are actually using 32-bit.

I am very aware of Virtual Memory, Code Segments, Data Segments, Stack Segments, Extra Segments, etc. Come from different physical memory in a 32-bit model. You can use 32-bit registers in REAL mode provided the processor is a 386 or above. There were no clear indications in their code that his person is pure Protected Mode. Granted they didn't have the tell-tale .ORG $100

Okay in reviewing his code, his crash dump clearly shows he's using 32-bit code!

my gcc port is DJGPP i think
how do i adjust the stack?

I installed MinGW since I'm running windows to get the GNU compiler for Windows.
And I modified your code. Your code would run but would crash in the end. I added returns to each function so it wasn't printing all the functions each time. Adding the return to _main solved the crash. It appears NASM-with the Win library doesn't need the .START declaration as it appears to be calling the procedure _main.

[section .data]	
hello: db 'Hello world!', 10, 0 ;15 bytes	
nl:    db ' ', 10, 0   ;3 bytes 



[section .text]	

global _main, _print_nl, _print_msg, _return	
extern _printf 



_print_nl:
	push	nl	
	call    _printf
	add     esp, 4
	ret

_print_msg:
	push    hello
	call    _printf
	add     esp, 4 
	ret

_return:
	mov     eax, 0
	ret

 
_main:
 	call	_print_msg
	call	_print_nl
	call    _print_msg
 	call    _return

	ret

I ran your code and it doesn't do anything :(

This is my code, the same thing but without the functions:

[section .data]	
	hello: db 'Hello world!', 10, 0 ;15 bytes	
	nl:    db ' ', 10, 0   ;3 bytes 

[section .text]	
	global _main
	extern _printf 
 
_main:
 	push	hello
	call    _printf
	add     esp, 4
	
	push    nl
	call    _printf
	add     esp, 4
	
	push    hello
 	call    _printf
 	add     esp, 4
 	
 	mov     eax, 0
 	ret

So EvenBit. I read the pdf. Read the NASM documents. My modified version of tomtetlaw's code works on the NASM and MinGW installations I had to install just to run his code, and it ran! I am using the standard C method CDECL calling conventions, just like in the PDF. I have no idea why his code doesn't run unless he has a different version of GNU which has other requirements. Except for a few quirks, NASM is similar to MASM, which is my primary assembler and that I have been programming professionally for a very long time.

Is the compiler he's using using fastcall, or stdcall instead of cdecl? CDECL is typically a C languge method.

So enlighten me please!

i don't know what my compiler uses :S

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.