AS.9
上传用户:datang2001
上传日期:2007-02-01
资源大小:53269k
文件大小:13k
源码类别:

操作系统开发

开发平台:

C/C++

  1. ." unchecked (kjb)
  2. .CD "as (en assembler"
  3. .SE "AS(emASSEMBLER [IBM]"
  4. .SP 1
  5. .PP
  6. This document describes the language accepted by the 80386 assembler
  7. that is part of the Amsterdam Compiler Kit.  Note that only the syntax is
  8. described, only a few 386 instructions are shown as examples.
  9. .SS "Tokens, Numbers, Character Constants, and Strings"
  10. .PP
  11. The syntax of numbers is the same as in C.
  12. The constants 32, 040, and 0x20 all represent the same number, but are
  13. written in decimal, octal, and hex, respectively.
  14. The rules for character constants and strings are also the same as in C.
  15. For example, (fma(fm is a character constant.
  16. A typical string is "string".
  17. Expressions may be formed with C operators, but must use [ and ] for
  18. parentheses.  (Normal parentheses are claimed by the operand syntax.)
  19. .SS "Symbols"
  20. .PP
  21. Symbols contain letters and digits, as well as three special characters:
  22. dot, tilde, and underscore.
  23. The first character may not be a digit or tilde.
  24. .PP
  25. The names of the 80386 registers are reserved.  These are:
  26. .HS
  27. ~~~al, bl, cl, dl
  28. .br
  29. ~~~ah, bh, ch, dh
  30. .br
  31. ~~~ax, bx, cx, dx, eax, ebx, ecx, edx
  32. .br
  33. ~~~si, di, bp, sp, esi, edi, ebp, esp
  34. .br
  35. ~~~cs, ds, ss, es, fs, gs
  36. .HS
  37. The xx and exx variants of the eight general registers are treated as
  38. synonyms by the assembler.  Normally "ax" is the 16-bit low half of the
  39. 32-bit "eax" register.  The assembler determines if a 16 or 32 bit
  40. operation is meant solely by looking at the instruction or the
  41. instruction prefixes.  It is however best to use the proper registers
  42. when writing assembly to not confuse those who read the code.
  43. .HS
  44. The last group of 6 segment registers are used for selector + offset mode
  45. addressing, in which the effective address is at a given offset in one of
  46. the 6 segments.
  47. .PP
  48. Names of instructions and pseudo-ops are not reserved.  
  49. Alphabetic characters in opcodes and pseudo-ops must be in lower case.
  50. .SS "Separators"
  51. .PP
  52. Commas, blanks, and tabs are separators and can be interspersed freely 
  53. between tokens, but not within tokens.
  54. Commas are only legal between operands.
  55. .SS "Comments"
  56. .PP
  57. The comment character is *(OQ!*(CQ.  
  58. The rest of the line is ignored.
  59. .SS "Opcodes"
  60. .PP
  61. The opcodes are listed below.
  62. Notes: (1) Different names for the same instruction are separated by *(OQ/*(CQ.
  63. (2) Square brackets ([]) indicate that 0 or 1 of the enclosed characters 
  64. can be included.
  65. (3) Curly brackets ({}) work similarly, except that one of the
  66. enclosed characters fImustfR be included.
  67. Thus square brackets indicate an option, whereas curly brackets indicate
  68. that a choice must be made.
  69. .sp
  70. .if t .ta 0.25i 1.2i 3i
  71. .if n .ta 2 10 24
  72. .nf
  73. .B "Data Transfer"
  74. .HS
  75. mov[b] dest, source ! Move word/byte from source to dest
  76. pop dest ! Pop stack 
  77. push source ! Push stack 
  78. xchg[b] op1, op2 ! Exchange word/byte 
  79. xlat ! Translate 
  80. o16 ! Operate on a 16 bit object instead of 32 bit
  81. .B "Input/Output"
  82. .HS
  83. in[b] source ! Input from source I/O port
  84. in[b] ! Input from DX I/O port
  85. out[b] dest ! Output to dest I/O port
  86. out[b] ! Output to DX I/O port
  87. .B "Address Object"
  88. .HS
  89. lds reg,source ! Load reg and DS from source
  90. les reg,source ! Load reg and ES from source
  91. lea reg,source ! Load effect address of source to reg and DS
  92. {cdsefg}seg ! Specify seg register for next instruction
  93. a16 ! Use 16 bit addressing mode instead of 32 bit
  94. .B "Flag Transfer"
  95. .HS
  96. lahf ! Load AH from flag register
  97. popf ! Pop flags 
  98. pushf ! Push flags 
  99. sahf ! Store AH in flag register
  100. .B "Addition"
  101. .HS
  102. aaa ! Adjust result of BCD addition
  103. add[b] dest,source ! Add 
  104. adc[b] dest,source ! Add with carry 
  105. daa ! Decimal Adjust after addition
  106. inc[b] dest ! Increment by 1
  107. .B "Subtraction"
  108. .HS
  109. aas ! Adjust result of BCD subtraction
  110. sub[b] dest,source ! Subtract 
  111. sbb[b] dest,source ! Subtract with borrow from dest
  112. das ! Decimal adjust after subtraction
  113. dec[b] dest ! Decrement by one
  114. neg[b] dest ! Negate 
  115. cmp[b] dest,source ! Compare
  116. .B "Multiplication"
  117. .HS
  118. aam ! Adjust result of BCD multiply
  119. imul[b] source ! Signed multiply
  120. mul[b] source ! Unsigned multiply
  121. .B "Division"
  122. .HS
  123. aad ! Adjust AX for BCD division
  124. o16 cbw ! Sign extend AL into AH
  125. o16 cwd ! Sign extend AX into DX
  126. cwde ! Sign extend AX into EAX
  127. cdq ! Sign extend EAX into EDX
  128. idiv[b] source ! Signed divide
  129. div[b] source ! Unsigned divide
  130. .B "Logical"
  131. .HS
  132. and[b] dest,source ! Logical and
  133. not[b] dest ! Logical not
  134. or[b] dest,source ! Logical inclusive or
  135. test[b] dest,source ! Logical test
  136. xor[b] dest,source ! Logical exclusive or
  137. .B "Shift"
  138. .HS
  139. sal[b]/shl[b] dest,CL ! Shift logical left
  140. sar[b] dest,CL ! Shift arithmetic right
  141. shr[b] dest,CL ! Shift logical right
  142. .B "Rotate"
  143. .HS
  144. rcl[b] dest,CL ! Rotate left, with carry
  145. rcr[b] dest,CL ! Rotate right, with carry
  146. rol[b] dest,CL ! Rotate left
  147. ror[b] dest,CL ! Rotate right
  148. .B "String Manipulation"
  149. .HS
  150. cmps[b] ! Compare string element ds:esi with es:edi
  151. lods[b] ! Load from ds:esi into AL, AX, or EAX
  152. movs[b] ! Move from ds:esi to es:edi
  153. rep ! Repeat next instruction until ECX=0
  154. repe/repz ! Repeat next instruction until ECX=0 and ZF=1
  155. repne/repnz ! Repeat next instruction until ECX!=0 and ZF=0
  156. scas[b] ! Compare ds:esi with AL/AX/EAX
  157. stos[b] ! Store AL/AX/EAX in es:edi
  158. .fi
  159. .B "Control Transfer"
  160. .PP
  161. fIAsfR accepts a number of special jump opcodes that can assemble to
  162. instructions with either a byte displacement, which can only reach to targets
  163. within (mi126 to +129 bytes of the branch, or an instruction with a 32-bit
  164. displacement.  The assembler automatically chooses a byte or word displacement
  165. instruction.
  166. .PP
  167. The English translation of the opcodes should be obvious, with
  168. *(OQl(ess)*(CQ and *(OQg(reater)*(CQ for signed comparisions, and
  169. *(OQb(elow)*(CQ and *(OQa(bove)*(CQ for unsigned comparisions.  There are
  170. lots of synonyms to allow you to write "jump if not that" instead of "jump
  171. if this".
  172. .PP
  173. The *(OQcall*(CQ, *(OQjmp*(CQ, and *(OQret*(CQ instructions can be 
  174. either intrasegment or
  175. intersegment.  The intersegment versions are indicated with 
  176. the suffix *(OQf*(CQ.
  177. .if t .ta 0.25i 1.2i 3i
  178. .if n .ta 2 10 24
  179. .nf
  180. .B Unconditional
  181. .HS
  182. jmp[f] dest ! jump to dest (8 or 32-bit displacement)
  183. call[f] dest ! call procedure
  184. ret[f] ! return from procedure
  185. .B "Conditional"
  186. .HS
  187. ja/jnbe ! if above/not below or equal (unsigned)
  188. jae/jnb/jnc ! if above or equal/not below/not carry (uns.)
  189. jb/jnae/jc ! if not above nor equal/below/carry (unsigned)
  190. jbe/jna ! if below or equal/not above (unsigned)
  191. jg/jnle ! if greater/not less nor equal (signed)
  192. jge/jnl ! if greater or equal/not less (signed)
  193. jl/jnqe ! if less/not greater nor equal (signed)
  194. jle/jgl ! if less or equal/not greater (signed)
  195. je/jz ! if equal/zero
  196. jne/jnz ! if not equal/not zero
  197. jno ! if overflow not set
  198. jo ! if overflow set
  199. jnp/jpo ! if parity not set/parity odd
  200. jp/jpe ! if parity set/parity even
  201. jns ! if sign not set
  202. js ! if sign set
  203. .B "Iteration Control"
  204. .HS
  205. jcxz dest ! jump if ECX = 0
  206. loop dest ! Decrement ECX and jump if CX != 0
  207. loope/loopz dest ! Decrement ECX and jump if ECX = 0 and ZF = 1
  208. loopne/loopnz dest ! Decrement ECX and jump if ECX != 0 and ZF = 0
  209. .B "Interrupt"
  210. .HS
  211. int n ! Software interrupt n
  212. into ! Interrupt if overflow set
  213. iretd ! Return from interrupt
  214. .B "Flag Operations"
  215. .HS
  216. clc ! Clear carry flag
  217. cld ! Clear direction flag
  218. cli ! Clear interrupt enable flag
  219. cmc ! Complement carry flag
  220. stc ! Set carry flag
  221. std ! Set direction flag
  222. sti ! Set interrupt enable flag
  223. .fi
  224. .SS "Location Counter"
  225. .PP
  226. The special symbol *(OQ.*(CQ is the location counter and its value 
  227. is the address of the first byte of the instruction in which the symbol 
  228. appears and can be used in expressions.
  229. .SS "Segments"
  230. .PP
  231. There are four different assembly segments: text, rom, data and bss.
  232. Segments are declared and selected by the fI.sectfR pseudo-op.  It is
  233. customary to declare all segments at the top of an assembly file like
  234. this:
  235. .HS
  236. ~~~.sect .text; .sect .rom; .sect .data; .sect .bss
  237. .HS
  238. The assembler accepts up to 16 different segments, but
  239. .MX
  240. expects only four to be used.  Anything can in principle be assembled
  241. into any segment, but the
  242. .MX
  243. bss segment may only contain uninitialized data.
  244. Note that the *(OQ.*(CQ symbol refers to the location in the current
  245. segment.
  246. .SS "Labels"
  247. .PP
  248. There are two types: name and numeric.  Name labels consist of a name
  249. followed by a colon (:).
  250. .PP
  251. The numeric labels are single digits.  The nearest 0: label may be
  252. referenced as 0f in the forward direction, or 0b backwards.
  253. .SS "Statement Syntax"
  254. .PP
  255. Each line consists of a single statement.
  256. Blank or comment lines are allowed.
  257. .SS "Instruction Statements"
  258. .PP
  259. The most general form of an instruction is
  260. .HS
  261. ~~~label: opcode operand1, operand2    ! comment
  262. .HS
  263. .SS "Expression Semantics"
  264. .PP
  265. .tr ~~
  266. The following operators can be used:
  267. + (mi * / & | ^ ~ << (shift left) >> (shift right) (mi (unary minus).
  268. .tr ~
  269. 32-bit integer arithmetic is used.  
  270. Division produces a truncated quotient.
  271. .SS "Addressing Modes"
  272. .PP
  273. Below is a list of the addressing modes supported.
  274. Each one is followed by an example.
  275. .HS
  276. .ta 0.25i 3i
  277. .nf
  278. constant mov eax, 123456
  279. direct access mov eax, (counter)
  280. register mov eax, esi
  281. indirect mov eax, (esi)
  282. base + disp. mov eax, 6(ebp)
  283. scaled index mov eax, (4*esi)
  284. base + index mov eax, (ebp)(2*esi)
  285. base + index + disp. mov eax, 10(edi)(1*esi)
  286. .HS
  287. .fi
  288. Any of the constants or symbols may be replacement by expressions.  Direct
  289. access, constants and displacements may be any type of expression.  A scaled
  290. index with scale 1 may be written without the *(OQ1**(CQ.
  291. .SS "Call and Jmp"
  292. .PP
  293. The *(OQcall*(CQ and *(OQjmp*(CQ instructions can be interpreted
  294. as a load into the instruction pointer.
  295. .HS
  296. .ta 0.25i 3i
  297. .nf
  298. call _routine ! Direct, intrasegment
  299. call (subloc) ! Indirect, intrasegment
  300. call 6(ebp) ! Indirect, intrasegment
  301. call ebx ! Direct, intrasegment
  302. call (ebx) ! Indirect, intrasegment
  303. callf (subloc) ! Indirect, intersegment
  304. callf seg:offs ! Direct, intersegment
  305. .HS
  306. .fi
  307. .SP 1
  308. .SS "Symbol Assigment"
  309. .SP 1
  310. .PP
  311. Symbols can acquire values in one of two ways.
  312. Using a symbol as a label sets it to *(OQ.*(CQ for the current
  313. segment with type relocatable.  
  314. Alternative, a symbol may be given a name via an assignment of the form
  315. .HS
  316. ~~~symbol = expression 
  317. .HS
  318. in which the symbol is assigned the value and type of its arguments.
  319. .SP 1
  320. .SS "Storage Allocation"
  321. .SP 1
  322. .PP
  323. Space can be reserved for bytes, words, and longs using pseudo-ops.
  324. They take one or more operands, and for each generate a value
  325. whose size is a byte, word (2 bytes) or long (4 bytes).  For example:
  326. .HS
  327. .if t .ta 0.25i 3i
  328. .if n .ta 2 24
  329. .data1 2, 6 ! allocate 2 bytes initialized to 2 and 6
  330. .br
  331. .data2 3, 0x10 ! allocate 2 words initialized to 3 and 16
  332. .br
  333. .data4 010 ! allocate a longword initialized to 8
  334. .br
  335. .space 40 ! allocates 40 bytes of zeros
  336. .HS
  337. allocates 50 (decimal) bytes of storage, initializing the first two
  338. bytes to 2 and 6, the next two words to 3 and 16, then one longword with
  339. value 8 (010 octal), last 40 bytes of zeros.
  340. .SS "String Allocation"
  341. .PP
  342. The pseudo-ops fI.asciifR and fI.ascizfR
  343. take one string argument and generate the ASCII character
  344. codes for the letters in the string. 
  345. The latter automatically terminates the string with a null (0) byte.
  346. For example,
  347. .HS
  348. ~~~.ascii "hello"
  349. .br
  350. ~~~.asciz "worlden"
  351. .HS
  352. .SS "Alignment"
  353. .PP
  354. Sometimes it is necessary to force the next item to begin at a word, longword
  355. or even a 16 byte address boundary.
  356. The fI.alignfR pseudo-op zero or more null byte if the current location
  357. is a multiple of the argument of .align.
  358. .SS "Segment Control"
  359. .PP
  360. Every item assembled goes in one of the four segments: text, rom, data,
  361. or bss.  By using the fI.sectfR pseudo-op with argument
  362. fI.text, .rom, .datafR or fI.bssfR, the programmer can force the
  363. next items to go in a particular segment.
  364. .SS "External Names"
  365. .PP
  366. A symbol can be given global scope by including it in a fI.definefR pseudo-op.
  367. Multiple names may be listed, separate by commas.
  368. It must be used to export symbols defined in the current program.
  369. Names not defined in the current program are treated as "undefined
  370. external" automatically, although it is customary to make this explicit
  371. with the fI.externfR pseudo-op.
  372. .SS "Common"
  373. .PP
  374. The fI.commfR pseudo-op declares storage that can be common to more than 
  375. one module.  There are two arguments: a name and an absolute expression giving
  376. the size in bytes of the area named by the symbol.  
  377. The type of the symbol becomes
  378. external.  The statement can appear in any segment.
  379. If you think this has something to do with FORTRAN, you are right.
  380. .SS "Examples"
  381. .PP
  382. In the kernel directory, there are several assembly code files that are
  383. worth inspecting as examples.
  384. However, note that these files, are designed to first be
  385. run through the C preprocessor.  (The very first character is a # to signal
  386. this.)  Thus they contain numerous constructs
  387. that are not pure assembler.
  388. For true assembler examples, compile any C program provided with 
  389. .MX
  390. using the fB(enSfR flag.
  391. This will result in an assembly language file with a suffix with the same
  392. name as the C source file, but ending with the .s suffix.