.text # sonoff is a subroutine to illustrate Intel IN, OUT instructions for # I/O, and OR/AND logical instructions # the parameter is 0 to turn the speaker off, 1 to turn it on # there is a one-byte I/O port at location 0x61; the least-significant 2 # bits must be set to 11 for the speaker to be on, 00 for off; the other # bits contain other important information and must not be changed! # note: in Linux, I/O can be done only in Kernel Mode # OR dest,src does the following: for every bit in src which is a 1, # the corresponding bit in dest is set to 1, leaving all other bits # intact # AND dest,src does the following: for every bit in src which is a 0, # the corresponding bit in dest is set to 0, leaving all other bits # intact .globl sonoff sonoff: cmpl 4(%esp), $0 # check parameter jz off # turn speaker on inb $0x61,%al # `b' refers to byte-sized operand, like `l' for long; # %al is AL, the lower byte of AX orb $3,%al # set 2 rightmost bits to 11, leaving all others intact outb %al,$0x61 ret off: inb $0x61,%al andb $0xfc,%al # put 00 in 2 rightmost bits, leaving all others intact outb %al,$0x61 ret # conoff is a subroutine to check whether the speaker is on, returning 0 # if off, 1 if on; again, note that we wish to keep the other bits at # port 0x61 intact .globl conoff conoff: inb $0x61, %al andb $3, %al jnz on # off movl $0, %eax ret on: movl $1, %eax ret # count1s is a subroutine to illustrate the Intel SHR instruction; it # counts the number of 1 bits in the parameter, returning the count in # EAX # SHR dest,src shifts dest to the right by src bits, filling in 0s on # the left end where bits are vacated by the shift # SHL does the same except that the shift is leftward, filling in 0s on # the right # the TEST instruction is the same as AND, but does not change the # destination; it simply sets the Flags register according to the result # of the AND operation (TEST is to AND as CMP is to SUB) .globl count1s count1s: pushl %ebx pushl %ecx movl $0, %eax # initialize 1s count movl $32, %ebx # initialize loop counter movl 12(%esp), %ecx # get parameter top: testl $1, %ecx jz bitnot1 #rightmost bit of ECX is a 1 incl %eax bitnot1: shrl $1, %ecx # `l' stands for long, as usual decl %ebx jnz top ret