Assembly wierdness
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
tomtetlaw
Practically a Master Poster
605 posts since Sep 2008
Reputation Points: 9
Solved Threads: 5
Can someone please help me?
tomtetlaw
Practically a Master Poster
605 posts since Sep 2008
Reputation Points: 9
Solved Threads: 5
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!
wildgoose
Practically a Posting Shark
896 posts since Jun 2009
Reputation Points: 546
Solved Threads: 99
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?
tomtetlaw
Practically a Master Poster
605 posts since Sep 2008
Reputation Points: 9
Solved Threads: 5
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?
tomtetlaw
Practically a Master Poster
605 posts since Sep 2008
Reputation Points: 9
Solved Threads: 5
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.
wildgoose
Practically a Posting Shark
896 posts since Jun 2009
Reputation Points: 546
Solved Threads: 99
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.
wildgoose
Practically a Posting Shark
896 posts since Jun 2009
Reputation Points: 546
Solved Threads: 99
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!
wildgoose
Practically a Posting Shark
896 posts since Jun 2009
Reputation Points: 546
Solved Threads: 99
my gcc port is DJGPP i think
how do i adjust the stack?
tomtetlaw
Practically a Master Poster
605 posts since Sep 2008
Reputation Points: 9
Solved Threads: 5
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
wildgoose
Practically a Posting Shark
896 posts since Jun 2009
Reputation Points: 546
Solved Threads: 99
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
tomtetlaw
Practically a Master Poster
605 posts since Sep 2008
Reputation Points: 9
Solved Threads: 5
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!
wildgoose
Practically a Posting Shark
896 posts since Jun 2009
Reputation Points: 546
Solved Threads: 99
i don't know what my compiler uses :S
tomtetlaw
Practically a Master Poster
605 posts since Sep 2008
Reputation Points: 9
Solved Threads: 5