Hi, I had problems with compiling a piece of code with gcc. It seems to produce asm output (for the gnu assembler) that it incorrect! The reason that I post this in linux-kernel is that it _may_ be an error cause of a header file in the linux-2.4.3 kernel. (I suspect asm/uaccess.h a lot). The version of gcc I use: gcc version 2.95.3 19991030 (prerelease) The version of as (there is no gas on the system): GNU assembler version 2.10.90 (i586-mandrake-linux) using BFD version 2.10.0.24 (I got the tools from the Mandrake 7.2 installation). My kernel version: 2.4.3 When I am compiling it with make I get the following output: gcc -c problem.c -D__KERNEL__ -DMODULE -DLINUX \ -I/usr/src/linux/include /tmp/cc2zGHRK.s: Assembler messages: /tmp/cc2zGHRK.s:147: Error: `%al' not allowed with `movl' make: *** [all] Error 1 ...which makes sence, al is an 8-bit register and cant be used with movl, or? The problematic source code follows: Makefile: all: gcc -c problem.c -D__KERNEL__ -DMODULE -DLINUX \ -I/usr/src/linux/include problem.c: #include <linux/kernel.h> #include <linux/module.h> #if CONFIG_MODVERSIONS==1 #define MODVERSIONS #include <linux/modversions.h> #endif #include <linux/proc_fs.h> #ifndef KERNEL_VERSION #define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c)) #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) #include <asm/uaccess.h> #endif #define MESSAGE_LENGTH 80 static char Message[MESSAGE_LENGTH]; #define PROC_FILENAME "myuid" #if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,0) static int module_output( struct inode *inode, /* The inode read */ struct file *file, /* The file read */ char *buf, /* The buffer to put data to (in the * user segment) */ int len) /* The length of the buffer */ #else static ssize_t module_output( struct file *file, /* The file read */ char *buf, /* The buffer to put data to (in the * user segment) */ size_t len, /* The length of the buffer */ loff_t *offset) /* Offset in the file - ignore */ #endif { static int finished = 0; int i; char message[MESSAGE_LENGTH+30]; if (finished) { finished = 0; return 0; } sprintf(message, "Last input:%s", Message); for(i=0; i<len && message[i]; i++) put_user(message[i], buf+i); finished = 1; return i; /* Return the number of bytes "read" */ } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) static ssize_t module_input( struct file *file, /* The file itself */ const char *buf, /* The buffer with input */ size_t length, /* The buffer's length */ loff_t *offset) /* offset to file - ignore */ #else static int module_input( struct inode *inode, /* The file's inode */ struct file *file, /* The file itself */ const char *buf, /* The buffer with the input */ int length) /* The buffer's length */ #endif { int i; for(i=0; i<MESSAGE_LENGTH-1 && i<length; i++) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) get_user(Message[i], buf+i); #else Message[i] = get_user(buf+i); #endif Message[i] = '\0'; /* we want a standard, zero * terminated string */ return i; } static int module_permission(struct inode *inode, int op) { /* Givetvis skall alla fa skriva till var fil! */ if (op==4 || op==2) return 0; return -EACCES; } int module_open(struct inode *inode, struct file *file) { MOD_INC_USE_COUNT; return 0; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) int module_close(struct inode *inode, struct file *file) #else void module_close(struct inode *inode, struct file *file) #endif { MOD_DEC_USE_COUNT; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) return 0; /* success */ #endif } static struct file_operations File_Ops_4_Our_Proc_File = { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) NULL, /* struct module *owner; */ #endif NULL, /* lseek/llseek */ module_output, /* "read" from the file */ module_input, /* "write" to the file */ NULL, /* readdir */ NULL, /* select/poll */ NULL, /* ioctl */ NULL, /* mmap */ module_open, /* Somebody opened the file */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) NULL, /* flush, added here in version 2.2 */ #endif module_close, /* Somebody closed the file */ /* Some more will follow */ }; static struct inode_operations Inode_Ops_4_Our_Proc_File = { #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) &File_Ops_4_Our_Proc_File, #endif NULL, /* create */ NULL, /* lookup */ NULL, /* link */ NULL, /* unlink */ NULL, /* symlink */ NULL, /* mkdir */ NULL, /* rmdir */ NULL, /* mknod */ NULL, /* rename */ NULL, /* readlink */ NULL, /* follow_link */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) NULL, /* readpage */ NULL, /* writepage */ NULL, /* bmap */ #endif NULL, /* truncate */ module_permission /* check for permissions */ }; /* Directory entry */ static struct proc_dir_entry Our_Proc_File = { 0, /* Inode number - ignore, it will be filled by * proc_register[_dynamic] */ sizeof(PROC_FILENAME)-1, /* Length of the file name */ PROC_FILENAME, /* The file name */ S_IFREG | S_IRUGO | S_IWUSR, /* File mode - this is a regular file which * can be read by its owner, its group, and everybody * else. Also, its owner can write to it. * * Actually, this field is just for reference, it's * module_permission that does the actual check. It * could use this field, but in our implementation it * doesn't, for simplicity. */ 1, /* Number of links (directories where the * file is referenced) */ 0, 0, /* The uid and gid for the file - * we give it to root */ 80, /* The size of the file reported by ls. */ &Inode_Ops_4_Our_Proc_File, /* A pointer to the inode structure for * the file, if we need it. In our case we * do, because we need a write function. */ NULL /* The read function for the file. Irrelevant, * because we put it in the inode structure above */ }; /* Initialize the module - register the proc file */ int init_module() { #if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,0) return proc_register_dynamic(&proc_root, &Our_Proc_File); #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) return proc_register(&proc_root, &Our_Proc_File); #else struct proc_dir_entry *dirent; dirent=create_proc_entry(PROC_FILENAME,S_IFREG|S_IRUGO,&proc_root); if (dirent==NULL) return 1; memset((void *)dirent,0,sizeof(dirent)); dirent->proc_iops=&Inode_Ops_4_Our_Proc_File; dirent->proc_fops=&File_Ops_4_Our_Proc_File; dirent->data=NULL; return 0; #endif } /* Cleanup - unregister our file from /proc */ void cleanup_module() { #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) proc_unregister(&proc_root,Our_Proc_File.low_ino); #else remove_proc_entry(PROC_FILENAME,&proc_root); #endif } Maybe you recognize parts of the code from the linux kernel module programming guide. It is yet not completed, I was stuck in this error before I had finished it. When I tried to only preprocess the code (to see if the error came from a header files inline asm) by using the -E switch to gcc I did not find anything special. When I tried to do everything except assembling and linking (with the -S switch to gcc) I got a file problem.s which I inspected. That file did contain a line like this (line 147): movl %al,(%edx) I am not sure this is correct assembly, but I have to admit that I am not yet very experienced on asm. Does this line really make sence? How do I move a long into al that is a 8-bit register? I have only tried this version of gcc so far. Best regards /Anders Lindén - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/