Hi all,

I'm an Assembly newby and am studying Jeff Duntemann's book on programming Assembly on Linux. As much as I love Assembly and I have to learn it if I want to do anything significant in IT since it's part of a journey, I am finding difficult to get started because there are so many variables.

My environment is Ubuntu (Linux Debian) 9.10 64-bit and I am using NASM as compiler. Following Duntemann's suggestion, I created a sort of "sandbox" program where I can simply run few instructions and see the effect that these have on registers.

This is the simple program I'm writing:

;  Executable name : 
;  Version         : 1.0
;  Created date    : 
;  Last update     : 
;  Author          : Marco Tedone
;  Description     : A template to create sandbox programs
;
;  Build using these commands:
;    nasm -f elf64 -g -F stabs <your-asm-name>.asm
;    ld -o <your-asm-name> <your-asm-name>.o
;

SECTION .data			; Section containing initialised data
  
SECTION .text			; Section containing code

global _start			; Linker needs this to find the entry point!
	
_start:  			; Write your instructions between the two noops
nop
mov eax,0
inc eax
mov ebx,eax
nop

SECTION .bss			; Section containing uninitialised variables

The program compiles fine but when I run it I get segmentation fault. Why?

Also here there is another program (which actually does something useful) which runs fine:

;  Executable name : EATSYSCALL
;  Version         : 1.0
;  Created date    : 1/7/2009
;  Last update     : 2/18/2009
;  Author          : Jeff Duntemann
;  Description     : A simple program in assembly for Linux, using NASM 2.05,
;    demonstrating the use of Linux INT 80H syscalls to display text.
;
;  Build using these commands:
;    nasm -f elf -g -F stabs eatsyscall.asm
;    ld -o eatsyscall eatsyscall.o
;

SECTION .data			; Section containing initialised data
	
	EatMsg: db "Eat at Marco's  !",10
	EatLen: equ $-EatMsg	
	
SECTION .bss			; Section containing uninitialized data	

SECTION .text			; Section containing code

global 	_start			; Linker needs this to find the entry point!
	
_start:
	nop			; This no-op keeps gdb happy...
	mov eax,4		; Specify sys_write call
	mov ebx,1		; Specify File Descriptor 1: Standard Output
	mov ecx,EatMsg		; Pass offset of the message
	mov edx,EatLen		; Pass the length of the message
	int 80H			; Make kernel call

	MOV eax,1		; Code for Exit Syscall
	mov ebx,0		; Return a code of zero	
	int 80H			; Make kernel call

Could anybody tell me what I'm doing wrong? Please note that the first program gives a segmentation fault even if i write a simple instruction such as mov eax,4 or something like that. Does the program need to do something useful not to get a segmentation error?

Thanks.

M.

Is it really a sandbox?

Because if it isn't, your test just runs garbage until it hits a problem.

Try adding

MOV eax,1		; Code for Exit Syscall
	mov ebx,0		; Return a code of zero	
	int 80H			; Make kernel call

to the end of your 'sandbox' test.

Well the "sandbox" was without the instructions. Basically the "real" sandbox is as follows:

;  Executable name : 
;  Version         : 1.0
;  Created date    : 
;  Last update     : 
;  Author          : Marco Tedone
;  Description     : A template to create sandbox programs
;
;  Build using these commands:
;    nasm -f elf64 -g -F stabs <your-asm-name>.asm
;    ld -o <your-asm-name> <your-asm-name>.o
;

SECTION .data			; Section containing initialised data

SECTION .text			; Section containing code

global 	_start			; Linker needs this to find the entry point!
	
_start:

  nop				; Write your instructions between the two noops


  nop				; Write your instructions between the two noops

SECTION .bss			; Section containing uninitialized data

But then the author invites us to try a single instruction to see the effect on the registers. I thought that t a simple instructions such as mov eax,4 would be harmful, not that it would cause a segmentation fault. Are you saying that I cannot simply move the direct value 4 to the register EAX and finish my program like that?

Not much of a sandbox then is it, if an empty one crashes.

Better re-read the notes again to see if you missed something.

This is the code which comes with the book:

section .data
section .text
	global	_start
_start:
	nop
; Put your experiments between the two nops...

; Put your experiments between the two nops...
	nop

If I run it I get a segmentation fault. Can you run it? What do you get?

Jeff Duntemann here. In my book, the "sandbox" idea is *not* a java-style sandbox (I chose the wrong word there; "test bench" might be better) but a very simple framework within which to execute one or only a few instructions while single-stepping them in the debugger and watching register and memory values change. The sandbox programs are not intended to be run, and they segfault when you try to run them because they lack the INT 80H call that returns control to Linux. *They're intended to be single-stepped only.* I'll try and make that clearer in the next edition of the book.

A little later on in the book, I explain how to create properly terminated, runnable programs. I did it this way because a runnable program without console I/O doesn't do you much good, and console I/O requires explanation of INT 80H kernel calls. I wanted a way to demonstrate individual machine instructions "hands on" before I got into software interrupts and console I/O.

I hope this helps some.

--73--

--JD--

This article has been dead for over six months. Start a new discussion instead.