Re: Nasm 0.99.01 available



Evenbit wrote:
On Jun 9, 8:48 am, "Jim Carlock" <anonym...@xxxxxxxxx> wrote:

I don't know. Nathan sounds like he's up to helping out in rewriting it
in NASM.


Well, it might be interesting to write some "interwebs" functionality
in NASM:

http://arsdnet.net/cgi-bin/a.out

;)


"Frank Kotler" <fbkotler@xxxxxxxxxxx> wrote...
: Segfaults. I think we need to do something a little more robust if we
: *don't* find the environment variables we're looking for. I'll look at
: it later. Thanks, Nathan!

Heh? Seg fault? What I get is posted after my signature. Perhaps you
mean it faults on your own machine?

I've already quit using Visual Studio 6. I've been playing around with
Pelles C. I should be able to get Pelles C to compile NASM, right?
Heck, I think I should be able to get Visual Studio 6 to work as well,
but I thought I'd give Pelles C a shot first, as it does come with the
inttypes.h file.

It's just not compiling the way I expected it to. The file formats are
ending up in some unknown format. I'm trying to use dumpbin.exe
to view the exports and imports and I'm not getting any.

I don't expect any help here, but if someone has already done this,
and knows what's going on, the help would be greatly appreciated.

The current error I'm working on...
insns.h(25): error #2001: Syntax error: found 'int32_t' - expecting '}'.

struct itemplate {
int opcode; /* the token, passed from "parser.c" */
int operands; /* number of operands */
int32_t opd[3]; /* bit flags for operand types (line25)*/
const char *code; /* the code it assembles to */
uint32_t flags; /* some flags */
};

As far as the wrong file type goes, I just need to figure out the proper
switches for the compiler, I believe.

--
Jim Carlock

NOTE: Only the contents of the page is displayed below. To view
the HTML, you'll need to click on the link below and then do the
"View Source" thing with your web-browser.
http://arsdnet.net/cgi-bin/a.out

; I just realized someone posted this to digg, so it might actually be seen :)
; The code comes after these paragraphs, and is lightly commented.

; Anyway, this is nothing special. It is just using CGI, like any other script
; (or program in C or whatever) can do, and all it does is echo some output
; and echo back your browser user-agent string (to demonstrate something
; dynamic). With some extension though, it could do some real work - GET
; variables are passed in in the environment variable QUERY_STRING, which is
; easily retreived with the framework already written and parsed with some
; relatively simple string processing code, and POST variables are sent through
; standard input (retrievable easily with the read() system call, file
; descriptor 0, just like you would in any other application). If you have done
; any CGI programming before, you'll realize this is how the standard works;
; there is nothing magical about asm in that. If you haven't, this is a fun
; way to start :P
; Also, things like cookies are simply HTTP headers, so outputting them is
; trivial as well; just put them after the Content-type (again, this is
; just standard, nothing magical here). With only a little more work, and
; some kind of project idea, I could easily make this into a serious web
; application.

; This code is made available under the GNU GPL, version 2, and is copyright
; Adam D. Ruppe, 2006. You can reach me by looking at my homepage,
; http://arsdnet.net

; Of course, I make no warranty of any kind, but if you want to ask me about
; the code, or asm and linux programming, my email address is on my homepage.

; I use the nasm assembler. This might work with other assemblers, but I never
; tried. This code is also written specifically for Linux. It won't work on
; any other OS, including the BSDs (since they format their system calls
; differently, so a translation layer is needed, which if you are a BSD user
; you'll probably have it installed, but still, the code here is Linux code.

; Have fun!

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;should probably change jmp nears to jmp shorts
section .data
header: db 'Content-type: text/html',10,10,
db '<html>',10,'<head>',10
db '<title>',0
title: db 'Hello World!',0
ptitle: db '</title>',10
db '</head>',10,'<body>',10,0

body: db '<p>Assembly Language<br /><em>It&#39;s not just for crazy old hackers anymore.</em></p>',10

db '<p>View my <a href="/hello.asm">source</a>.</p>',10,0
pfoot: db '</body>',10,'</html>',10,0


;; padded to 20 bytes each, so string1+20 always = string2

env_names:
db 'HTTP_COOKIE',0,0,0,0,0
cookie: dd 0

db 'HTTP_REFERER',0,0,0,0
referer: dd 0

db 'HTTP_USER_AGENT',0
user_agent: dd 0

db 'QUERY_STRING',0,0,0,0
query_string: dd 0

db 'REMOTE_ADDR',0,0,0,0,0
remote_addr: dd 0

db 'REQUEST_METHOD',0,0
request_method: dd 0

db 0 ; a null we can check to see if we are finished

number_variables equ 6

section .text
global _start
_start:


;; now, I am going to loop through all the command line arguments, and pop them off the stack, since I don't care about them

pop eax ; argc
..popargv:
pop eax ; argv
or eax,eax ; set the zero flag if it is zero...
jnz .popargv ; if it is not NULL, keep going

;; next thing we pop should be a pointer to the first environment variable.



;;;;;;;
;; Here is my plan for the environment variables:
;; this will go through the stack, looking for the ones we care about
;; the strings of the ones we want will be in the data section,
;; NULL terminated. Right after this terminator, will be a dd where
;; I will store a pointer to the variable's actual data (which is nul termed).
;;;;;;;


..popenv:
mov esi,env_names
pop eax ; get the pointer to the next variable
or eax,eax
jz near .envdone ; null pointer; we are done


;; compare the string from the env stack to our list of wants
mov edi,eax
..again:
call strcmp
or al,al ; if [esi] at the point of difference is a zero
; or if strings are equal, we have the right variable
jz near .gotit

add esi,20 ; add the padding amount so we are at the next string

mov al,[esi]
or al,al

jz near .popenv ; all done checking this variable; no hits, so move on
jmp near .again ; move on
..gotit:
add edi, ecx ; add length of the string so we are pointing to the value
mov [esi+16],edi ; save the pointer


jmp near .popenv ; move on to the next
..envdone




;; first off, the needed headers

mov esi,header
call puts

mov esi,title
call puts

mov esi,ptitle
call puts

mov esi,body
call puts


mov esi,[remote_addr]
call puts

mov esi,[user_agent]
call puts


mov esi,pfoot
call puts



mov eax,1 ; (sys_exit)
mov ebx,0 ; return code
int 80h ; and we're done!

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; strcmp Compares a NULL terminated string at esi to one at edi
;;;
;;; preserves all registers except for eax and ecx, which carries the
;;; return value. 0 if the strings are equal, nonzero if not
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

strcmp:
cmp esi,0 ; do a quick check to make sure we aren't working with
je .return ; nul pointers
cmp edi,0
je .return


push esi
push edi

xor eax,eax

..continue:
mov al,[esi]
mov ah,[edi]

inc esi
inc edi

or al,al ; if either one is 0, then we have reached the end
jz near .done ; of the string and should not go on
or ah,ah
jz near .done

cmp al,ah
jz near .continue

..done:

; cmp al,ah

; setne al

; and eax,000000ffh

;; if the two strings are equal, then eax == 0, since both will be at their null terminators. Otherwise, it will be nonzero, which
fits the requirements of the description
mov ecx,esi
pop edi
pop esi
sub ecx,esi ; the length of the string

..return:
ret



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; puts Puts a NULL terminated string to standard output
;;; (like puts(3) in C)
;;;
;;; Put the offset to the string you want to put into esi
;;;
;;; Preserves all registers, no relevant return value.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

puts:

cmp esi,0 ; do a quick check to make sure we aren't working with
je .return ; a nul pointer

;; preserve the registers we will be smashing

push esi
push eax
push ebx
push ecx
push edx

mov ebx,1 ; file descriptor 1 is standard output
mov ecx,esi ; offset of data
;; length of data belongs in edx, lets calculate it
xor edx,edx
..count:
mov al,[esi]
or al,al
jz near .done
inc edx
inc esi
jmp near .count
..done

mov eax,4 ; sys_write

int 80h ; And call the kernel

;; put the registers and stack back how we found it

pop edx
pop ecx
pop ebx
pop eax
pop esi
..return:
ret
section .bss



.



Relevant Pages