Prev: masm linking from console
Next: NASM HelloWorld - DOS
From: Wolfgang Kern on 25 Jul 2007 04:27 Rod Pemberton answered: > Okay, the splash screen comes up with a bunch of check boxes and then > invalid instruction error: > HEXTUTOR executed an invalid instruction in > module HEXTUTOR.EXE at 0167:0041aaf2. > Registers: > EAX=00000001 CS=0167 EIP=0041aaf2 EFLGS=00010246 > EBX=00000000 SS=016f ESP=0054fca0 EBP=0054fce8 > ECX=00000000 DS=016f ESI=00008d40 FS=1097 > EDX=80005170 ES=016f EDI=0054fcd0 GS=0000 > Bytes at CS:EIP: > 0f 45 15 40 30 40 00 0f 44 15 3c 30 40 00 51 0f Yes, this is CMOVNZ edx,[00403040h] CMOVZ edx,[0040303ch] PUSH ecx .... > Stack dump: > 0041aaa8 0041a3f3 0041a291 0054fcd0 00008d40 0054fce8 > 0054fccc 0054fd1c 00008d5c 00000000 00000000 bff7363b > 00000b2c 0000000f 00000000 00000000 > 32-bit PM? Yes, also if the 'disass.com' is started from DOS prompt to become a PM32-TSR-module (once added for the few 32-bit DOS coders) > cmovnz and/or cmovz ? Yeah, and it uses SETcc/BT/BTC/BTS/BTR as well. > They're unsupported by my CPU... I see, and there might be more DX486 out there and still running ... > Do you detect CPU via CPUID? Not yet, but now I'm asked for, at least to mention minimal requirements. Thanks a lot Rod, I'll change the readme.txt right now and check the amount of work for 386/486 code versions. __ wolfgang
From: Herbert Kleebauer on 25 Jul 2007 15:13 Frank Kotler wrote: > I haven't figured out why the "direct to binary" version isn't working. Tried to do some testing but NASM is nothing but a disaster. Is it real possible to write any working assembly program with it? Now I understand why beginners prefer to use HLA. Maybe you can enlighten me: If I use "nasm -l v1.lst -O999 -f bin -o v1 v1.asm" to assemble this code: ======================================================================== org $08048000 dd $ offs equ $1000 aab equ $+offs dd aab I get an output file with the expected content: 00000 00 80 04 08 � 04 90 04 08 � But in the list file: 1 org $08048000 2 00000000 [00000000] dd $ 3 offs equ $1000 4 aab equ $+offs 5 00000004 [04100000] dd aab the values given are without the org value which makes the listing pretty useless. There also is no listing of all used labels or have I to use some switch? ======================================================================== If i use this program org $08048000 dd $ aab equ $+offs dd aab offs equ $1000 I would have expected the same output but get: 00000 00 80 04 08 � 04 10 00 00 � The listing is the same, but with a missing []: 1 org $08048000 2 00000000 [00000000] dd $ 3 aab equ $+offs 4 00000004 04100000 dd aab 5 offs equ $1000 ======================================================================== And if I use: org $08048000 dd $ aaa equ $+offs dd aaa offs equ $1000 I get: v3.asm:3 error: expression syntax error v3.asm:4 error: expression syntax error Is this because aaa is an instruction name? Why does this prevent aaa to be used as a label? And why isn't a proper error message used. I use the label within a macro and always tried to understand what's wrong with the macro.
From: Frank Kotler on 25 Jul 2007 15:59 Herbert Kleebauer wrote: > Frank Kotler wrote: > > >>I haven't figured out why the "direct to binary" version isn't working. > > > Tried to do some testing but NASM is nothing but a disaster. Short answer, for now... I've never found Nasm's listing files to be the least bit useful. In "-f bin" mode, you can ask for a map file: [map all myprog.map] In the source code (it's not a command line switch because it applies only to binary output (normally, a map file would be a linker function). Try that and see if you find it more useful. Best, Frank
From: Herbert Kleebauer on 26 Jul 2007 17:02 Frank Kotler wrote: > I haven't figured out why the "direct to binary" version isn't working. Here a working version. It's ugly, but either NASM is missing some important features or I don't understand how to proper use NASM. The nop's are in again so I could do a binary compare with the original binary. ; nasm -O999 -f bin -o myprog myprog.asm ;=========================================================================== %macro dc.b 2+ %ifidn %1,- %else %1 equ $+offs2 %endif db %2 %endmacro %macro dc.w 2+ %ifidn %1,- %else %1 equ $+offs2 %endif dw %2 %endmacro %macro dc.l 2+ %ifidn %1,- %else %1 equ $ + offs2 %endif dd %2 %endmacro ;=========================================================================== ; don't remove the following line and use offs directly ; this seems to be a bug in NASM offs2 equ offs ;=========================================================================== @1 equ $08048000 ; virtual address of code start @@1 equ 0 ; file byte address of code start org @1 code_offset equ @@1 code_addr: ;=========================================================================== ;--------------------------- ELF header ----------------------------------- dd $464c457f,$00010101,0,0,$00030002,1,main,$34,0,0,$00200034,2,0 dd 1,code_offset,code_addr,code_addr,code_filez,code_memsz,5,4096 dd 1,data_offset,data_addr,data_addr,data_filez,data_memsz,6,4096 ;--------------------------- code ------------------------------------------ USE32 main: mov [stack_ptr], esp ; save initial stack pointer ; ******************** get socket handle *************************** push 0 ; no protocol specified push 1 ; 1: SOCK_STREAM (/usr/include/linux/net.h) push 1 ; 1: AF_UNIX, AF_LOCAL (/usr/include/linux/socket.h) mov ecx, esp ; pointer to parameter for "socket" mov ebx, 1 ; "socket" (/usr/include/linux/net.h) mov eax, 102 ; socketcall (/usr/include/asm/unistd.h) int 80h add esp, 3 * 4 ; free space for parameters test eax, eax ; ERROR js err ; my apologies for propagating this sloppiness. ; really should be "cmp eax, -4096" (or -4095?) ; won't happen here, but we *could* get a ; valid return over 2G! - fbk mov [x_handle], eax ; ********** connect socket to /tmp/.X11-unix/X0" ****************** push sockaddr_un_l push sockaddr_un ; (/usr/include/linux/un.h) push dword [x_handle] ; socket handle mov ecx, esp ; pointer to parameter for "connect" mov ebx, 3 ; "connect" (/usr/include/linux/net.h) mov eax, 102 ; socketcall (/usr/include/asm/unistd.h) int 80h add esp, 3 * 4 ; free space for parameters test eax, eax ; ERROR js err ; *************** make socket read non blocking ******************* mov ebx, [x_handle] ; socket handle mov ecx, 3 ; F_GETFL (/usr/include/asm/fcntl.h) mov eax, 55 ; fcntl (/usr/include/asm/unistd.h) int 80h test eax, eax ; ERROR js err mov ebx, [x_handle] ; socket handle mov ecx, 4 ; F_SETFL (/usr/include/asm/fcntl.h) mov edx, eax or edx, 800h ; O_NONBLOCK (/usr/include/asm/fcntl.h) mov eax, 55 ; fcntl (/usr/include/asm/unistd.h) int 80h test eax, eax ; ERROR js err ; ******************* send connect message ************************* mov eax, send1 ; pointer to connect message mov edx, send1l call get_xauth ; try to read .Xauthority jc _11 ; no success, let's try without auth. mov [send1+6], bx ; insert name length mov [send1+8], si ; insert data length call x_send ; send header mov eax, ecx ; pointer to name lea edx, [ebx + 3] ; pad to a multiple of 4 and edx, -4 call x_send ; send name mov eax, ebp ; pointer to data lea edx, [esi + 3] ; pad to a multiple of 4 and edx, -4 _11: call x_send ; send data xor ebp, ebp ; number of total bytes read mov esi, buf2 ; pointer to buffer for next read mov edi, buf2l ; max. bytes to read .10: mov eax, esi mov edx, edi call x_receive_raw jz .10 ; but we need a reply cmp byte [buf2], 1 ; success jne err ; something went wrong add ebp, eax ; total read bytes add esi, eax ; pointer to buffer for next read sub edi, eax ; max. bytes to read cmp ebp, 8 ; at least 8 bytes read? jc .10 ; no, get more movzx ebx, word [buf2 + 6] ; additional data in 4 bytes lea ebx, [ebx * 4 + 8] ; total size in bytes cmp ebp, ebx ; all read jc .10 ; no, get more ; ******************* calculate id's ******************************* mov esi, buf2 mov eax, [esi + 0Ch] ; resource_id_base mov edx, [esi + 10h] ; resource_id_mask mov ecx, edx neg ecx and edx, ecx ; resource_id_incr mov [s2a], eax ; wid for CreateWindow mov [s3a], eax ; wid for MapWindow mov [s4a], eax ; wid for CreateDC mov [s5a], eax ; wid for CreateDC mov [s6a], eax ; wid for SetInputFocus add eax, edx ; next id mov [s4b], eax ; cid for CreateDC mov [s5b], eax ; cid for CreateDC add eax, edx ; next id ; lint!!! ; mov [resource_id_next], eax ; mov [resource_id_incr], edx ; ******************* get root window id *************************** movzx eax, word [esi + 18h] ; length of vendor string add eax, 28h + 3 ; const header length + round vendor length and al, -4 ; round to 4 bytes movzx edx, byte [esi + 1Dh] ; number of FORMATs shl edx, 3 ; 8 byte for each FORMAT entry add edx, eax ; offset to root WINDOW id mov eax, [esi + edx] ; root window mov [s2b], eax ; CreateWindow needs root window id mov eax, [esi + edx + 20] ; width/height of root window mov [s2x], eax ; create window full size sub eax, (200 << 16) + 320 shr eax, 1 and eax, 0FFFF7FFFh mov [s5x], eax ; center drawing ; ******************* send CreatWindow request ********************* mov eax, send2 mov edx, send2l call x_send call x_receive jz .20 ; no message is a good message cmp byte [eax], 0 ; error message je ende ; ******************* send MapWindow request *********************** .20: mov eax, send3 mov edx, send3l call x_send call x_receive jz .30 ; no message is a good message cmp byte [eax], 0 ; error message je ende ; ******************* send CreatDC request ************************* .30: mov eax, send4 mov edx, send4l call x_send call x_receive jz .40 ; no message is a good message cmp byte [eax], 0 ; error message je ende ; ******************* send SetInputFocust ************************* .40: mov eax, send6 mov edx, send6l call x_send call x_receive jz .60 ; no message is a good message cmp byte [eax], 0 ; error message je ende .60: call init_color ; init 64 VGA colors ; ******************** main loop *************************** .50: call annie ; generate next picture call display call x_receive jz .50 ; no message is a good message cmp byte [eax], 0 ; error message je err cmp byte [eax], 2 ; key press je ende cmp byte [eax], 4 ; button press jne .50 err: ende: mov ebx, 0 ; return code mov eax, 1 ; exit int 80h ;------------------------------------------ display: mov esi, screen mov ecx, 20 ; we use 20 parts to make each less than 16k ..10 mov eax, send5 mov edx, send5l call x_send mov eax, esi mov edx, 320 * 10 * 4 ; size of one part call x_send add word [s5y], 10 ; update y pos for next part add esi, 320*10*4 ; update source pointer for next part loop .10 sub word [s5y], 20*10 ; restore original y position ret ;----------------------------------------- ; ********* Annie's code to draw a heart **************** annie: pusha xor ebx, ebx .10: inc dword [annie1] mov ecx, 320 * 200 xor edi, edi .20: mov eax, edi ; byte pos in screen xor edx, edx mov ebx, 320 ; 320 lines div ebx ; eax: line 0-199 edx: column 0-319 sub eax, 120 ; center y=120 (-120 .. +79) sub edx, 160 ; x=160 (-160 .. +159) jg .30 neg edx ; symmetric in x (0 .. 160) .30: mov ebx, eax imul ebx, ebx ; ebx = x*x add eax, edx ; eax = x*x+y imul eax ; eax = (x*x+y)**2 mod 2*16 add ebx, eax jz .40 xor edx, edx mov eax, 600000 div ebx .40: add eax, [annie1] ; change color shr al, 2 movzx eax, al mov eax, [color+ eax * 4] mov [screen + edi * 4], eax inc edi loop .20 popa nop ret ; ****************** initialize 64 VGA colors ********************* init_color: pusha mov esi, color mov eax, 0 ; sic mov ecx, 64 _01: mov [esi], eax add esi, 4 add al, 10h add ax, 800h add eax, 40000h loop _01 popa nop ret ;********************************************************** ;******** read cookie from $home/.Xauthority ************** ;********************************************************** ; * ; input: stack_ptr: original sp at program start * ; output: C=0: cookie found in $home/.Xauthority * ; r2: pointer to protocol name * ; r3: length of protocol name * ; r4: pointer to protocol data * ; r5: length of protocol data * ; C=1: nothing found * ; r2/r3/r4/r5 undefined * ; * ; typedef struct xauth { * ; unsigned short family; * ; unsigned short address_length; * ; char *address; * ; unsigned short number_length; * ; char *number; * ; unsigned short name_length; * ; char *name; * ; unsigned short data_length; * ; char *data; * ; } Xauth; * ;********************************************************** get_xauth: push eax push edx push edi mov edi, [stack_ptr] ; original stack pointer at program start mov eax, [edi] ; number of arguments lea edi, [edi + eax * 4 + 8] ; skip arguments + trailing null pointer .20: mov esi, [edi] ; pointer to next env variable add edi, 4 test esi, esi ; no more env variables jz .notfound cmp dword [esi], 'HOME' ; HOME found? jne .20 ; no, try next cmp byte [esi + 4], '=' ; HOME= found? jne .20 ; no, try next add esi, 5 ; start of HOME path or ecx, -1 .30: inc ecx ; count length of HOME path cmp byte [esi + ecx], 0 jne .30 or ecx, ecx ; at least one char long? jz .notfound ; no, HOME is empty cmp ecx, 256 ; more than 256 charcters ja .notfound ; somebody tries a buffer overflow mov edi, fname ; buffer for filename rep movsb ; copy HOME path mov eax, '/.Xa' ; 'aX./' ; add .Xauthority stosd mov eax, 'utho' ; 'ohtu' stosd mov eax, 'rity' ; 'ytir' stosd mov byte [edi], 0 ; and a trailing 0 mov ebx, fname xor ecx, ecx ; readonly mov eax, 5 ; open int 80h test eax, eax ; file open error? js .notfound ; yes mov ebx, eax ; file handle mov ecx, buf2 mov edx, buf2l ; read 1024 byte mov eax, 3 ; read int 80h cmp eax, buf2l jnc err ; .Xauthority >= 1024 byte mov ebp, eax ; bytes read mov eax, 6 ; close int 80h test ebp, ebp ; file empty jz .notfound mov esi, buf2 add ebp, esi ; end of read data xor eax, eax .60: lodsw ; family dec ax jz .40 ; 1=FamilyLocal mov ecx, 4 ; skip entry .50: lodsw ror ax, 8 ; big -> little endian add esi, eax loop .50 cmp esi, ebp ; more data jc .60 ; try next entry ..notfound: stc jmp _70 .40: mov ecx, 2 mov ebx, ecx .41: lodsw ror ax, 8 add esi, eax ; skip address/number loop .41 .42: lodsw ror ax, 8 mov ecx, esi mov ebx, eax add esi, ebx lodsw ror ax, 8 mov ebp, esi mov esi, eax clc _70: pop edi pop edx pop eax ret ;********************************************************** ;******** send message to X server ************** ;********************************************************** ; input: eax: pointer to message * ; edx: length of message * ;********************************************************** x_send: pusha mov ebp, eax ; pointer to next byte of message mov esi, edx ; remaining bytes to send .20: push 0 ; flags push esi ; length push ebp ; pointer to data push dword [x_handle] ; socket handle mov ecx, esp ; pointer to parameter for "send" mov ebx, 9 ; "send" (/usr/include/linux/net.h) mov eax, 102 ; socketcall (/usr/include/asm/unistd.h) int 80h add esp, 4*4 ; free space for parameters cmp eax, -11 ; EAGAIN: je .20 ; message couldn't be sent, try again test eax, eax ; ERROR js err sub esi, eax ; remaining bytes to send jz .30 ; nothing, all sent add ebp, eax ; pointer to remaining message jmp .20 ; send rest of message .30: popa nop ret ;********************************************************** ;******** receive ONE message from X server ********** ;********************************************************** ; input: none * ; output: Z=1: no complete message available * ; eax/edx undefined * ; Z=0: eax: pointer to message data * ; edx: size of data * ;********************************************************** x_receive: push ecx push esi push edi _00: mov eax, [buf2_rest] ; still something in read buffer? cmp eax, 32 ; a message has at least 32 bytes jnc .10 ; maybe it is a complete message .30: mov esi, [buf2_ptr] ; start of message mov edi, buf2 ; start of buffer mov [buf2_ptr], edi ; we copy message to top of buffer cmp edi, esi ; already at top of buffer je .50 ; then nothing to copy or eax, eax ; nothing in buffer jz .50 ; then also nothing to copy mov ecx, eax ; copy to top of buffer rep movsb .50: mov edx, buf2l ; let's try to get some more data sub edx, eax ; not more bytes than space is left in the buf lea eax, [buf2 + eax] ; append it here call x_receive_raw jnz .20 ; we could read something jmp _100 ; return with Z=1 .20: add [buf2_rest], eax ; now we have a few more bytes in the buffer jmp _00 ; let's try again .10: mov esi, [buf2_ptr] ; let's test if it is a complete meesage cmp byte [esi], 34 ja err ; the last known message is nr 34 mov edx, 32 ; cmp byte [esi], 0 ; error message ; je .40 cmp byte [esi], 1 ; reply message jne .40 ; event message is always 32 byte add edx, [esi + 12] ; + additional data for reply add edx, [esi + 12] ; + additional data for reply add edx, [esi + 12] ; + additional data for reply add edx, [esi + 12] ; + additional data for reply cmp eax, edx ; complete reply in buffer jc .30 ; no, let's try to get more .40: mov eax, esi ; pointer to data sub [buf2_rest], edx ; new rest add [buf2_ptr], edx ; pointer to next data; clear Z flag _100: pop edi pop esi pop ecx ret ;********************************************************** ;******** read data from X server ********** ;********************************************************** ; input: eax: pointer to read buffer * ; edx: size of buffer * ; output: Z=1: nothing to read * ; Z=0: eax bytes read * ;********************************************************** x_receive_raw: push ecx push ebx push 0 ; flags push edx ; bytes to read push eax ; pointer to buffer push dword [x_handle] ; socket handle mov ecx, esp ; pointer to parameter for "recv" mov ebx, 10 ; "recv" (/usr/include/linux/net.h) mov eax, 102 ; socketcall (/usr/include/asm/unistd.h) int 80h add esp, 4 * 4 ; free space for parameters pop ebx pop ecx cmp eax, -11 ; EAGAIN: no message available -> Z=1 je .10 test eax, eax ; <0: ERROR 0: NULL message -> Z=1 js err .10: ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;--------------------------- constant data --------------------------------- ; (note that we're in .text, not .rdata) align 4 sockaddr_un: dw 1 ; 1: AF_UNIX, AF_LOCAL (/usr/include/linux/socket.h) db "/tmp/.X11-unix/X0" sockaddr_un_l equ $ - sockaddr_un ;--------------------------------------------------------------------------- ;--------------------------------------------------------------------------- ;=========================================================================== ; end of code and constant data section ;=========================================================================== align 4 @2 equ @1 + ($-code_addr);virtual address of end of code @@2 equ @2-@1 ; file byte address of end of code code_filez equ @@2-@@1 code_memsz equ @2-@1 @3 equ (@2+4095) / 4096 * 4096+(@@2 % 4096) ; virtual address of data start @@3 equ @@2 ; file byte address of data start offs equ @3-@2 ; diff between NASM $ and virt. addr. data section data_offset equ @@3 data_addr equ $+offs2 ;=========================================================================== ; start of data section ; ; you MUST NOT use db/dw/dd to define data, use dc.b/dc.w/dc.l instead ;=========================================================================== ;--------------------------- initialized data ------------------------------ dc.l buf2_ptr, buf2 dc.l buf2_rest, 0 ; Connection Setup dc.b send1 , $6c,0 ; LSB first dc.w - , 11,0 ; major/minor version dc.w - , 0,0 ; length of protocol name/data dc.w - , 0 ; unused send1l equ $+offs2 - send1 ; Create Window dc.b send2 , 1 ; opcode for Create Window dc.b - , 0 ; depth from parent dc.w - , send2l/4; request length dc.l s2a , 0 ; wid (has to be calculated) dc.l s2b , 0 ; parent (has to be calculated) dc.w - , 0 ; x dc.w - , 0 ; y dc.w s2x , 640 ; width dc.w s2y , 400 ; heigth dc.w - , 0 ; border-width dc.w - , 0 ; class: CopyFromParent dc.l - , 0 ; visual: CopyFromParent dc.l - , 0A02h ; value-mask: background-pixel 2 ; + override-redirect 200 ; + event-mask 800 dc.l - , 0 ; background: black dc.b - , 1 ; override-redirect = true dc.b - , 0,0,0 ; pad dc.l - , 5 ; event_mask: KeyPress 1 ; +ButtenPress 4 ; +PointerMotion 40 send2l equ (($+offs2 - send2)+3) & 0fffffffch ; Map Window dc.b send3 , 8 ; opcode for Map Window dc.b - , 0 ; unused dc.w - , send3l/4; request length dc.l s3a , 0 ; wid (has to be calculated) send3l equ $+offs2 - send3 ; Create GC dc.b send4 , 55 ; opcode for CreateGC dc.b - , 0 ; unused dc.w - , send4l/4; request length dc.l s4b , 0 ; cid (has to be calculated) dc.l s4a , 0 ; wid (has to be calculated) dc.l - , 1+4+8 ; function+foreground+background dc.l - , 3 ; function=copy dc.l - , 0ffffffh ; foreground: white dc.l - , 0080ffh ; background: light blue send4l equ $+offs - send4 ; Put Image dc.b send5 , 72 ; opcode for PutImage dc.b - , 2 ; ZPixmap dc.w - , send5l/4 + 320*10*4/4 ; request length dc.l s5a , 0 ; wid (has to be calculated) dc.l s5b , 0 ; cid (has to be calculated) dc.w - , 320 ; width dc.w - , 200/20 ; height dc.w s5x , 0 ; dest-x dc.w s5y , 0 ; dest-y dc.b - , 0 ; left-pad dc.b - , 24 ; depth dc.w - , 0 ; unused send5l equ $+offs2 - send5 ; Set Input Focus dc.b send6 , 42 ; opcode for SetInputFocus dc.b - , 0 ; revert-to None dc.w - , send6l/4; request length dc.l s6a , 0 ; wid (has to be calculated) dc.l - , 0 ; timestamp CurrentTime send6l equ $+offs2 - send6 ;=========================================================================== @4 equ @3 + ($+offs2)-data_addr ; virtual address of end of data @@4 equ data_offset + ($+offs2)-data_addr ;file byte addr.of e.o.d section .bss resb offs2 ; now NASM $ and virt. address are synchron again @5 equ $ ; virtul address of start of unitialized data ;=========================================================================== ;--------------------------- uninitialized data ---------------------------- screen: resd 320*200 ; bitmap stack_ptr: resd 1 x_handle: resd 1 annie1: resd 1 color: resd 64 fname: resb 256+32 buf2: resb 1024 buf2l equ $ - buf2 ;--------------------------------------------------------------------------- ;=========================================================================== @6 equ $ ; virtual address of end of unitialzed data data_filez equ @@4-@@2 data_memsz equ @4-@3 + @6-@5 ;===========================================================================
From: T.M. Sommers on 27 Jul 2007 08:02
Herbert Kleebauer wrote: > "T.M. Sommers" wrote: >>Rod Pemberton wrote: > >>>>>case 0x05: {la[--j] = la[j] / la[j+1]; break;} >>>> >>>I.e., assuming LALR(1) and applying precedence, the above is: >>>case 0x05: >>>{ >>> --j; >>> la[j] = la[j] / la[j+1]; >>> break; >>>} >>> >>>It appears that DJGPP (GCC) works properly while OpenWatcom v1.3 fails. I'd >>>guess that most K&R style compilers work. >> >>The origial line invokes undefined behavior; anything the >>compiler does is "proper". > > Then you have a very bizarre definition of "proper". No, you do. The standard allows a compiler to do anything it wants when it encounters undefined behavior. There is no way to say that one compiler is right and another wrong. > It isn't a > problem when the behaviour for such a construct is undefined in the > C specification. The problem arises when an implementation of the C > specification defines the behaviour for this construct. The problem is that the two compilers are allowed to do different things, and no one can say one is right and the other wrong. > If the > behaviour would still be undefined in the implementation, then > the compiler would emit an error message an stop if it encounter > this construct. It would be also no problem if all compilers would > implement the same behaviour (and so extend the C specification > in a consistent manner). Sure, the standard could be changed, but today you have to deal with it as it is. > But how should you get aware of the > problem with a construct like "la[--j] = la[j] / la[j+1];" if > it exactly does what you suppose it to do with the compiler you > use? By learning the language properly. -- Thomas M. Sommers -- tms(a)nj.net -- AB2SB |