|
|
1.1 ! root 1: ! 2: ! 3: as Command as ! 4: ! 5: ! 6: ! 7: ! 8: i8086 assembler ! 9: ! 10: aass [-ggllxx] [ -oo_f_i_l_e ] _f_i_l_e ... ! 11: ! 12: as is the Mark Williams assembler. It is a multipass assembler ! 13: that turns files of assembly language into relocatable object ! 14: modules similar to those produced by the compiler. as is ! 15: designed for writing small assembly-language subroutines. ! 16: Because it is not intended to be used for full-scale assembly- ! 17: language programming, it lacks many of the more elaborate ! 18: facilities of full-fledged assemblers. For example, there are no ! 19: facilities for conditional compilation or user-defined macros. ! 20: However, it does optimize span-dependent instructions (for ex- ! 21: ample, branches). ! 22: ! 23: ***** Features ***** ! 24: ! 25: as includes the following features: ! 26: ! 27: * It automatically compiles jump instructions into either ! 28: regular (three-byte) jumps or short (two-byte) jumps, ! 29: whichever is required. There is no explicit short jump in- ! 30: struction. ! 31: ! 32: * The assembler supports temporary labels, which conserves sym- ! 33: bol table space and relieves the you of having to invent many ! 34: unique labels. ! 35: ! 36: * Program modules are relocatable. They can be linked with each ! 37: other and with C program modules produced by the COHERENT com- ! 38: piler. All assembled modules must be linked before they can ! 39: be executed. ! 40: ! 41: * The assembler does not support file inclusion, but multiple ! 42: source files can be concatenated and assembled by including ! 43: their names in the command line to run the assembler. ! 44: ! 45: * The assembler generates SMALL model objects in the COHERENT ! 46: l.out object format. ! 47: ! 48: ***** Usage ***** ! 49: ! 50: Normally, the assembler is invoked via the cccc command, which will ! 51: automatically assemble and link any file of source code that has ! 52: the suffix .ss. If you wish, however, you can invoke the as- ! 53: sembler as a separate program, by using the following command ! 54: line: ! 55: ! 56: ! 57: aass [-ggllxx] [ -oo _f_i_l_e ] _f_i_l_e ... ! 58: ! 59: ! 60: The named _f_i_l_es are concatenated and the resulting object code is ! 61: written to the file specified by the -o option, or to file l.out ! 62: ! 63: ! 64: COHERENT Lexicon Page 1 ! 65: ! 66: ! 67: ! 68: ! 69: as Command as ! 70: ! 71: ! 72: ! 73: if no -o option is given. ! 74: ! 75: The option -g causes all symbols that are undefined at the end of ! 76: the first pass to be given the type undefined external, as though ! 77: they had been declared with a .globl directive. ! 78: ! 79: The option -l tells the assembler to generate a listing. It ! 80: writes the listing to the standard output, normally the terminal; ! 81: it may be easily redirected to a file or printer using the > ! 82: operator. ! 83: ! 84: The option -x strips from the symbol table of the object module ! 85: all non-global symbols that begin with the character `L'. This ! 86: speeds up the loading of files by removing compiler-generated ! 87: labels from the symbol table. ! 88: ! 89: ***** Register Names ***** ! 90: ! 91: The following lists the identifiers that represent the i8086 ! 92: machine registers, which are predefined: ! 93: ! 94: ! 95: AX SP AL AH CS ! 96: BX BP BL BH DS ! 97: CX SI CL CH ES ! 98: DX DI DL DH SS ! 99: ! 100: ! 101: ***** Lexical Conventions ***** ! 102: ! 103: Assembler tokens consist of identifiers (also known as ``sym- ! 104: bols'' or ``names''), constants, and operators. ! 105: ! 106: An identifier is a sequence of alphanumeric characters (including ! 107: the period `.' and the underscore `_'). The first character must ! 108: not be numeric. Only the first 16 characters of the name are ! 109: significant; it throws away the remainder. Upper case and lower ! 110: case are different. The machine instructions, assembly direc- ! 111: tives, and built-in symbols that are used frequently are in lower ! 112: case. ! 113: ! 114: Numeric constants are defined by the assembler by using the same ! 115: syntax as the C compiler: a sequence of digits that begins with a ! 116: zero `0' is an octal constant; a sequence of digits with a ! 117: leading `0x' is a hexadecimal constant (`A' through `F' have the ! 118: decimal values 10 through 15); and any strings of digits that do ! 119: not begin with `0' are interpreted as decimal constants. ! 120: ! 121: A character constant consists of an apostrophe followed by an ! 122: ASCII character. The constant's value is the ASCII code for the ! 123: character, right-justified in the machine word. For example, an ! 124: instruction to move the letter `A' to the register al could be ! 125: expressed in either of two equivalent ways: ! 126: ! 127: ! 128: ! 129: ! 130: COHERENT Lexicon Page 2 ! 131: ! 132: ! 133: ! 134: ! 135: as Command as ! 136: ! 137: ! 138: ! 139: ! 140: mov al,$0x41 ! 141: mov al,$'A ! 142: ! 143: ! 144: The dollar sign indicates an immediate operand. ! 145: ! 146: A blank space can be represented either 00xx2200 (its ASCII value in ! 147: hexadecimal), or as an apostrophe followed by a space (' ), which ! 148: on paper looks like just an apostrophe alone. ! 149: ! 150: The following gives the multi-character escape sequences that can ! 151: be used in a character constant to represent special characters: ! 152: ! 153: ! 154: \bb Backspace (0010) ! 155: \ff Formfeed (0014) ! 156: \nn Newline (0012) ! 157: \rr Carriage return(0015) ! 158: \tt Tab (0011) ! 159: \vv Vertical tab (0013) ! 160: \_n_n_n Octal value (0_n_n_n) ! 161: ! 162: ! 163: A blank space can be represented either as 0x20 (its ASCII value ! 164: in hexadecimal), or as an apostrophe followed by a space (' ), ! 165: which on the page would look like just an apostrophe. ! 166: ! 167: ***** Blanks and Tabs ***** ! 168: ! 169: Blanks and tab characters may be used freely between tokens, but ! 170: not within identifiers. A blank or a tabulation character is ! 171: required to separate adjacent tokens not otherwise separated, ! 172: e.g., between an instruction opcode and its first operand. ! 173: ! 174: ***** Comments ***** ! 175: ! 176: Comments are introduced by a slash (`/') and continue until the ! 177: end of the line. All characters in comments are ignored by the ! 178: assembler. ! 179: ! 180: ***** Program Sections ***** ! 181: ! 182: The assembler permits you to divide programs into sections, each ! 183: corresponding (roughly) to a functional area of the address ! 184: space. Each program section has its own location counter during ! 185: assembly. There are eight program sections, subdivided into ! 186: three groups containing code, data and tables: ! 187: ! 188: ! 189: code: sshhrrii Shared instruction ! 190: bbssssii Uninitialized instruction ! 191: pprrvvii Private instruction ! 192: data: pprrvvdd Private data ! 193: sshhrrdd Shared data ! 194: ! 195: ! 196: COHERENT Lexicon Page 3 ! 197: ! 198: ! 199: ! 200: ! 201: as Command as ! 202: ! 203: ! 204: ! 205: bbssssdd Uninitialized data ! 206: ssttrrnn Strings ! 207: tables: ssyymmtt Symbol table ! 208: ! 209: ! 210: All Mark Williams assemblers use the same set of sections. This ! 211: increases the portability of programs between operating systems. ! 212: Not all the sections are distinct under COHERENT, however; the ! 213: meanings of the sections under (including hints as to how the C ! 214: compiler uses them) are as follows: ! 215: ! 216: shri (shared instruction) is the same as prvi (private instruc- ! 217: tion); the adjective shared refers to the sharing of physical ! 218: memory between two or more concurrent processes. prvi is used ! 219: for all code generated by the C compiler. ! 220: ! 221: Similarly, there is no distinction between shrd and prvd. The ! 222: compiler uses the latter for all external and static data that ! 223: are explicitly initialized in a C program. ! 224: ! 225: Uninitialized sections are actually initialized to zeros. The ! 226: reason is that the C compiler uses the bssd (uninitialized data) ! 227: section for external or static data that are not explicitly in- ! 228: itialized: the C language guarantees that these data are in fact ! 229: initialized to zeros. The bssi (uninitialized instruction) sec- ! 230: tion is not used by the compiler. ! 231: ! 232: The strn (strings) section is actually a special part of the data ! 233: section, used by the C compiler to store string constants. It is ! 234: synonymous with prvd under COHERENT. ! 235: ! 236: The symt (symbol table) section contains the symbol table used by ! 237: the linker. Both the C compiler and the assembler generate sym- ! 238: bol tables that go in this section. ! 239: ! 240: In most cases, you need not worry about what all these program ! 241: sections are, and can simply write code under the keyword .prvi ! 242: or .shri, and write data under the keyword .prvd or .shrd. You ! 243: are advised not to place items in the symt section, as this sec- ! 244: tion is used for internal communication among the C compiler, the ! 245: assembler, and the linker. ! 246: ! 247: At the end of assembly, the sections of a program are con- ! 248: catenated so that in the assembly listing the program looks like ! 249: a monolithic block of code and data. All ccooddee sections are com- ! 250: bined into the i8086 ccooddee segment, and all ddaattaa sections into the ! 251: i8086 ddaattaa segment. The symbol table is not linked when the ! 252: program is executed, and so is not assigned to any i8086 segment. ! 253: ! 254: ***** The Current Location ***** ! 255: ! 256: The special symbol `.' (period) is a counter that represents the ! 257: current location. The current location can be changed by an as- ! 258: signment; for example: ! 259: ! 260: ! 261: ! 262: COHERENT Lexicon Page 4 ! 263: ! 264: ! 265: ! 266: ! 267: as Command as ! 268: ! 269: ! 270: ! 271: ! 272: . = .+START ! 273: ! 274: ! 275: The assignment must not cause the value to decrease, and it must ! 276: not change the program section, i.e., the right-hand operand must ! 277: be defined in the same section as the current section. ! 278: ! 279: ***** Expressions ***** ! 280: ! 281: An expression is a sequence of symbols representing a value and a ! 282: program section. Expressions are made up of identifiers, con- ! 283: stants, operators, and brackets. All binary operators have equal ! 284: precedence and are executed in a strict left-to-right order (un- ! 285: less altered by brackets). ! 286: ! 287: Notice that square brackets, `[' and `]', group expression ! 288: elements, because parentheses are used for indexed register ad- ! 289: dressing. ! 290: ! 291: ***** Types ***** ! 292: ! 293: Every expression has a type determined by its operands. The ! 294: simplest operands are symbols. The types of symbols are as ! 295: follows: ! 296: ! 297: Undefined A symbol is defined if it is a constant or a label, or ! 298: when assigned a defined value; otherwise, it is un- ! 299: defined. A symbol may become undefined if it is as- ! 300: signed the value of an undefined expression. It is an ! 301: error to assemble an undefined expression in pass 2. ! 302: Pass 1 allows assembly of undefined expressions, but ! 303: phase errors may be produced if undefined expressions ! 304: are used in certain contexts, such as in a .blkw or ! 305: .blkb. ! 306: ! 307: Absolute An absolute symbol is one defined ultimately from a ! 308: constant or from the difference of two relocatable ! 309: values. ! 310: ! 311: Register These are the machine registers. ! 312: ! 313: Relocatable ! 314: All other user symbols are relocatable symbols in some ! 315: program section. Each program section is a different ! 316: relocatable type. ! 317: ! 318: Each keyword in the assembler has a secret type that identifies ! 319: it internally; however, all of these secret types are converted ! 320: to absolute in expressions. Thus, any keyword may be used in an ! 321: expression to obtain the basic value of the keyword. This is ! 322: useful when employing the keywords that define machine instruc- ! 323: tions. The basic value of a machine operation is usually the op- ! 324: code with any operand-specific bits set to zero. ! 325: ! 326: ! 327: ! 328: COHERENT Lexicon Page 5 ! 329: ! 330: ! 331: ! 332: ! 333: as Command as ! 334: ! 335: ! 336: ! 337: Notice that the type of an expression does not include such at- ! 338: tributes as length (word or byte), so the assembler will not ! 339: remember whether you defined a particular variable to be a word ! 340: or a byte. Addresses and constants have different types, but the ! 341: assembler does not treat a constant as an immediate value unless ! 342: it is preceded by a dollar sign `$'. If you use a constant where ! 343: an address is expected, aass will treat the constant like an ad- ! 344: dress (and vice versa). It is up to you to distinguish between ! 345: variables and addresses or immediate values. ! 346: ! 347: ***** Operators ***** ! 348: ! 349: The following figure shows various characters interpreted as ! 350: operators in expressions. ! 351: ! 352: ! 353: + Addition ! 354: - Subtraction ! 355: * Multiplication ! 356: - Unary negation ! 357: ~ Unary complement ! 358: ^ Type transfer ! 359: | Segment construction ! 360: ! 361: ! 362: You can group expressions by means of square brackets (`[' and ! 363: `]'); parentheses are reserved for use in address mode descrip- ! 364: tions. ! 365: ! 366: ***** Type Propagation ***** ! 367: ! 368: When operands are combined in expressions, the resulting type is ! 369: a function of both the operator and the types of the operands. ! 370: The operators `*', `~', and unary `-' can only manipulate ab- ! 371: solute operands and always yield an absolute result. ! 372: ! 373: The operator `+' signifies the addition of two absolute operands ! 374: to yield an absolute result, and the addition of an absolute to a ! 375: relocatable operand to yield a result with the same type as the ! 376: relocatable operand. ! 377: ! 378: The binary operator `-' allows two operands of the same type, in- ! 379: cluding relocatable, to be subtracted to yield an absolute ! 380: result. It also allows an absolute to be subtracted from a ! 381: relocatable, to yield a result with the same type as the relocat- ! 382: able operand. ! 383: ! 384: The binary operator `^' yields a result with the value of its ! 385: left operand and the type of its right operand. It may be used ! 386: to create expressions (usually intended to be used in an assign- ! 387: ment statement) with any desired type. ! 388: ! 389: ***** Statements ***** ! 390: ! 391: A program consists of a sequence of statements separated by ! 392: ! 393: ! 394: COHERENT Lexicon Page 6 ! 395: ! 396: ! 397: ! 398: ! 399: as Command as ! 400: ! 401: ! 402: ! 403: newlines or by semicolons. There are four kinds of statements: ! 404: null statements, assignment statements, keyword statements, and ! 405: machine instructions. ! 406: ! 407: ***** Labels ***** ! 408: ! 409: You can precede any statement by any number of labels. There are ! 410: two kinds of labels: _n_a_m_e _l_a_b_e_l_s and _t_e_m_p_o_r_a_r_y _l_a_b_e_l_s. ! 411: ! 412: A name label consists of an identifier followed by a colon (:). ! 413: The program section and value of the label are set to that of the ! 414: current location counter. It is an error for the value of a ! 415: label to change during an assembly. This most often happens when ! 416: an undefined symbol is used to control a location counter adjust- ! 417: ment. ! 418: ! 419: A temporary label consists of a digit (00 to 99) followed by a ! 420: colon (:). Such a label defines temporary symbols of the form ! 421: xxff and xxbb, where xx is the digit of the label. References of the ! 422: form xxff refer to the first temporary label xx: forward from the ! 423: reference; those of the form xxbb refer to the first temporary ! 424: label xx: backward from the reference. Such labels conserve sym- ! 425: bol table space in the assembler. ! 426: ! 427: ***** Null Statements ***** ! 428: ! 429: A null statement is an empty line, or a line containing only ! 430: labels or a comment. Null statements can occur anywhere. They ! 431: are ignored by the assembler, except that any labels are given ! 432: the current value of the location counter. ! 433: ! 434: ***** Assignment Statements ***** ! 435: ! 436: An assignment statement consists of an identifier followed by an ! 437: equal sign `=' and an expression. The value and program section ! 438: of the identifier are set to that of the expression. Any symbol ! 439: defined by an assignment statement may be redefined, either by ! 440: another assignment statement or by a label. An assignment ! 441: statement is equivalent to the equ keyword statement found in ! 442: many assemblers. ! 443: ! 444: ***** Assembler Directives ***** ! 445: ! 446: Assembler directives give instructions to the assembler. Each ! 447: directive keyword begins with a period, and in general they are ! 448: followed by operands. ! 449: ! 450: The following directives change the current program section to ! 451: the named section: ! 452: ! 453: ! 454: ! 455: ! 456: ! 457: ! 458: ! 459: ! 460: COHERENT Lexicon Page 7 ! 461: ! 462: ! 463: ! 464: ! 465: as Command as ! 466: ! 467: ! 468: ! 469: .bssd ! 470: .bssi ! 471: .prvd ! 472: .prvi ! 473: .shrd ! 474: .shri ! 475: .strn ! 476: .symt ! 477: ! 478: ! 479: The current location counter is set to the highest previous value ! 480: of the location counter for the selected section. ! 481: ! 482: The following describes the directives in detail. ! 483: ! 484: .aasscciiii _s_t_r_i_n_g ! 485: The first non-white space character, typically a quotation ! 486: mark, after the keyword is taken as a delimiter. as as- ! 487: sembles successive characters from the string into succes- ! 488: sive bytes until it encounters the next instance of this ! 489: delimiter. To include a quotation mark in a string, use ! 490: some other character for the delimiter. ! 491: ! 492: It is an error for a newline to be encountered before ! 493: reaching the final delimiter. You can use a multi-character ! 494: constant in the string to represent newlines and other ! 495: special characters. ! 496: ! 497: .bbllkkbb _e_x_p_r_e_s_s_i_o_n ! 498: Assemble a block of bytes that are filled with zeroes. The ! 499: block is expression bytes long. ! 500: ! 501: .bbllkkww _e_x_p_r_e_s_s_i_o_n ! 502: Assemble a block of words that are filled with zeroes. The ! 503: block is expression words long. ! 504: ! 505: .bbyyttee _e_x_p_r_e_s_s_i_o_n [, _e_x_p_r_e_s_s_i_o_n ] ! 506: The _e_x_p_r_e_s_s_i_o_ns in the list are truncated to byte size and ! 507: assembled into successive bytes. Expressions in the list ! 508: are separated by commas. ! 509: ! 510: .eevveenn ! 511: Force alignment by inserting a null byte of data, if neces- ! 512: sary, to set the location counter to the next even location. ! 513: ! 514: .oodddd ! 515: Force alignment by inserting a null byte of data, if neces- ! 516: sary, to set the location counter to the next odd location. ! 517: ! 518: .gglloobbll _i_d_e_n_t_i_f_i_e_r [, _i_d_e_n_t_i_f_i_e_r ] ! 519: The identifiers in the comma-separated list are marked as ! 520: global. If they are defined in the current assembly, they ! 521: may be referenced by other object modules; if they are un- ! 522: defined, they must be resolved by the linker before execu- ! 523: tion. ! 524: ! 525: ! 526: COHERENT Lexicon Page 8 ! 527: ! 528: ! 529: ! 530: ! 531: as Command as ! 532: ! 533: ! 534: ! 535: ! 536: .ppaaggee ! 537: Force the printed listing of your assembly-language program ! 538: to skip to the top of a new page by inserting a form-feed ! 539: character into the file. The title is printed at the top of ! 540: the page. ! 541: ! 542: .ttiittllee _s_t_r_i_n_g ! 543: Print string at the top of every page in the listing. This ! 544: directive also causes the listing to skip to a new page. ! 545: ! 546: .wwoorrdd _e_x_p_r_e_s_s_i_o_n [, _e_x_p_r_e_s_s_i_o_n ] ! 547: Truncate _e_x_p_r_e_s_s_i_o_ns to word length and assemble the resul- ! 548: ting data into successive words. Expressions in the list ! 549: are separated by commas. ! 550: ! 551: ***** Address Descriptors ***** ! 552: ! 553: The following syntax is used for general source and destination ! 554: address descriptors. The symbol `r' refers to a register and the ! 555: symbol `e' to an expression. Please refer to the following ! 556: figure. ! 557: ! 558: ! 559: _S_y_n_t_a_x _A_d_d_r_e_s_s_i_n_g _M_o_d_e _E_x_a_m_p_l_e ! 560: ! 561: r Register mov ax, cx ! 562: e Direct address mov ax, 0800 ! 563: (r) Indexing, no displacement movax, (bx) ! 564: e(r) Indexing with displacement movax, 2(bx) ! 565: (r,r) Double indexing, no displacementmov ax, (bx, si) ! 566: e(r,r) Double indexing with displacementmov ax, 2(bx, si) ! 567: $e Immediate mov ax, $0800 ! 568: ! 569: ! 570: Note that the dollar sign is always used to indicate an immediate ! 571: value, even if the expression is a constant. ! 572: ! 573: A direct address is interpreted as either a direct address or a ! 574: PC-relative displacement, depending on the requirements of the ! 575: instruction. ! 576: ! 577: If an address descriptor indicates an indexing mode and the base ! 578: expression is of type absolute, the assembler uses the shortest ! 579: displacement length (zero, one, or two bytes) that can hold the ! 580: expression's value. Relocatable base expressions, whose values ! 581: cannot be completely determined until the program is loaded, are ! 582: always assigned two-byte displacements. ! 583: ! 584: Any address descriptor may be modified by a segment escape ! 585: prefix. A segment escape prefix consists of a segment register ! 586: name followed by a colon `:'. The escape causes the assembler to ! 587: produce a segment override prefix that uses the specified segment ! 588: register as an operand. The assembler does not produce segment ! 589: override prefixes unless explicitly required by an instruction. ! 590: ! 591: ! 592: COHERENT Lexicon Page 9 ! 593: ! 594: ! 595: ! 596: ! 597: as Command as ! 598: ! 599: ! 600: ! 601: ! 602: ***** 8086 Instructions ***** ! 603: ! 604: The following machine instructions are defined. The examples ! 605: illustrate the general syntax of the operands. Combinations that ! 606: are syntactically valid may be forbidden for semantic reasons. ! 607: ! 608: The examples use the following references: ! 609: ! 610: ! 611: _a General address ! 612: _a_l AL register ! 613: _a_x AX register ! 614: _c_l CL register ! 615: _d Direct address ! 616: _d_x DX register ! 617: _e Expression ! 618: $_e Immediate expression ! 619: _m Memory address (not an immediate) ! 620: _p Port address ! 621: ! 622: ! 623: aass treats as ordinary one-byte machine operations some operations ! 624: that the Intel assembler ASM86 handles with special syntax; these ! 625: include the _l_o_c_k and _r_e_p_e_a_t prefixes. aass makes no attempt to ! 626: prevent the generation of incorrect sequences of these prefix ! 627: bytes. ! 628: ! 629: Although every machine operation has a type and value associated ! 630: with it, in most cases the value was chosen to help aass format the ! 631: machine instructions. ! 632: ! 633: For more information on these instructions, see the Intel ASM86 ! 634: Assembly Language Reference Manual. ! 635: ! 636: aaaaaa ASCII adjust AL after addition ! 637: aaaadd ASCII adjust AX before division ! 638: aaaamm ASCII adjust AX after multiply ! 639: aaaass ASCII adjust AL after subtraction ! 640: aaddccbb _r, _a Add with carry, byte ! 641: aaddcc _r, _a Add with carry, word ! 642: aaddccbb _a, _r Add with carry, byte ! 643: aaddcc _a, _r Add with carry, word ! 644: aaddccbb _a, $_e Add with carry, byte ! 645: aaddcc _a, $_e Add with carry, word ! 646: aaddddbb _r, _a Add, byte ! 647: aadddd _r, _a Add, word ! 648: aaddddbb _a, _r Add, byte ! 649: aadddd _a, _r Add, word ! 650: aaddddbb _a, $_e Add, byte ! 651: aadddd _a, $_e Add, word ! 652: aannddbb _r, _a Logical and, byte ! 653: aanndd _r, _a Logical and, word ! 654: aannddbb _a, _r Logical and, byte ! 655: aanndd _a, _r Logical and, word ! 656: ! 657: ! 658: COHERENT Lexicon Page 10 ! 659: ! 660: ! 661: ! 662: ! 663: as Command as ! 664: ! 665: ! 666: ! 667: aannddbb _a, $_e Logical and, byte ! 668: aanndd _a, $_e Logical and, word ! 669: ccaallll _d Near call, PC-relative ! 670: ccbbww Convert byte into word ! 671: ccllcc Clear carry flag ! 672: cclldd Clear direction flag ! 673: ccllii Clear interrupt flag ! 674: ccmmcc Complement carry flag ! 675: ccmmppbb _r, _a Compare two operands, byte ! 676: ccmmpp _r, _a Compare two operands, word ! 677: ccmmppbb _a, _r Compare two operands, byte ! 678: ccmmpp _a, _r Compare two operands, word ! 679: ccmmppbb _a, $_e Compare two operands, byte ! 680: ccmmpp _a, $_e Compare two operands, word ! 681: ccmmppss Compare string operands, bytes ! 682: ccmmppssbb Compare string operands, bytes ! 683: ccmmppssww Compare string operands, words ! 684: ccwwdd Convert word to double ! 685: ddaaaa Decimal adjust AL after addition ! 686: ddaass Decimal adjust AL after subtraction ! 687: ddeeccbb _a Decrement by one, byte ! 688: ddeecc _a Decrement by one, word ! 689: ddiivvbb _m Unsigned divide, byte ! 690: ddiivv _m Unsigned divide, word ! 691: eesscc _a Escape 00xxDD88 ! 692: hhlltt Halt ! 693: iiccaallll _a Near call, absolute offset at EA word ! 694: iiddiivvbb _m Signed divide, byte ! 695: iiddiivv _m Signed divide, word ! 696: iijjmmpp _a Jump short, absolute offset at EA word ! 697: iimmuullbb _m Signed multiply, byte ! 698: iimmuull _m Signed multiply, word ! 699: iinnbb _a_l, _p Input, byte ! 700: iinn _a_x, _p Input, word ! 701: iinnbb _a_l, _d_x Input, byte ! 702: iinn _a_x, _d_x Input, word ! 703: iinnccbb _a Increment by one, byte ! 704: iinncc _a Increment by one, word ! 705: iinntt _e Call to interrupt ! 706: iinnttoo Call to interrupt, overflow ! 707: iirreett Interrupt return ! 708: jjaa _d Jump short if greater ! 709: jjaaee _d Jump short if greater or equal ! 710: jjbb _d Jump short if less ! 711: jjbbee _d Jump short if less or equal ! 712: jjcc _d Jump short if carry ! 713: jjccxxzz _d Jump short if CX equals zero ! 714: jjee _d Jump short if equal to ! 715: jjgg _d Jump short if greater ! 716: jjggee _d Jump short if greater or equal ! 717: jjll _d Jump short if less ! 718: jjllee _d Jump short if less or equal ! 719: jjmmpp _d Jump short, PC-relative word offset ! 720: jjmmppbb _d Jump short, PC-relative byte offset ! 721: jjmmppll _d Jump long ! 722: ! 723: ! 724: COHERENT Lexicon Page 11 ! 725: ! 726: ! 727: ! 728: ! 729: as Command as ! 730: ! 731: ! 732: ! 733: jjnnaa _d Jump short if not above ! 734: jjnnaaee _d Jump short if not above or equal ! 735: jjnnbb _d Jump short if not below ! 736: jjnnbbee _d Jump short if not below or equal ! 737: jjnncc _d Jump short if not carry ! 738: jjnnee _d Jump short if not equal ! 739: jjnngg _d Jump short if not greater ! 740: jjnnggee _d Jump short if not greater or equal ! 741: jjnnll _d Jump short if not less ! 742: jjnnllee _d Jump short if not less or equal ! 743: jjnnoo _d Jump short if not overflow ! 744: jjnnpp _d Jump short if not parity ! 745: jjnnss _d Jump short if not sign ! 746: jjnnzz _d Jump short if not zero ! 747: jjoo _d Jump short if overflow ! 748: jjpp _d Jump short if parity ! 749: jjppee _d Jump short if parity even ! 750: jjppoo _d Jump short if parity odd ! 751: jjss _d Jump short if sign ! 752: jjzz _d Jump short if zero ! 753: llaahhff Load flags into AH register ! 754: llddss _r, _a Load double pointer into DS ! 755: lleeaa _r, _a Load effective address offset ! 756: lleess _r, _a Load double pointer into ES ! 757: lloocckk Assert BUS LOCK signal ! 758: llooddssbb Load byte into AL ! 759: llooddss Load byte into AL ! 760: llooddssww Load byte into AL ! 761: lloooopp _d Loop; decrement CX, jump short ! 762: if CX less than zero ! 763: llooooppee _d Loop; decrement CX, jump short ! 764: if CZ not zero and equal ! 765: llooooppnnee _d Loop; decrement CX, jump short ! 766: if CX not zero and not equal ! 767: llooooppnnzz _d Loop; decrement CX, jump short ! 768: if CZ not zero and ZF equals zero ! 769: llooooppzz _d Loop; decrement CX, jump short ! 770: if CX not zero and zero ! 771: mmoovvbb _r, _a Move, byte ! 772: mmoovv _r, _a Move, word ! 773: mmoovvbb _a, _r Move, byte ! 774: mmoovv _a, _r Move, word ! 775: mmoovvbb _a, $_e Move, byte ! 776: mmoovv _a, $_e Move, word ! 777: mmoovvbb _a, _s Move, byte ! 778: mmoovv _a, _s Move, word ! 779: mmoovvbb _s, _a Move, byte ! 780: mmoovv _s, _a Move, word ! 781: mmoovvssbb Move string byte-by-byte ! 782: mmoovvss Move string word-by-word ! 783: mmoovvssww Move string word-by-word ! 784: mmuullbb _m Multiply, byte ! 785: mmuull _m Multiply, word ! 786: nneeggbb _a Two's complement negation, byte ! 787: nneegg _a Two's complement negation, word ! 788: ! 789: ! 790: COHERENT Lexicon Page 12 ! 791: ! 792: ! 793: ! 794: ! 795: as Command as ! 796: ! 797: ! 798: ! 799: nnoopp No operation ! 800: nnoottbb _a One's complement negation, byte ! 801: nnoott _a One's complement negation, word ! 802: oorrbb _r, _a Logical inclusive OR, byte ! 803: oorr _r, _a Logical inclusive OR, word ! 804: oorrbb _a, _r Logical inclusive OR, byte ! 805: oorr _a, _r Logical inclusive OR, word ! 806: oorrbb _a, $_e Logical inclusive OR, byte ! 807: oorr _a, $_e Logical inclusive OR, word ! 808: oouuttbb _p, _a_l Output to port, byte ! 809: oouutt _p, _a_x Output to port, word ! 810: oouuttbb _d_x, _a_l Output to port, byte ! 811: oouutt _d_x, _a_x Output to port, word ! 812: ppoopp _m Pop a word from the stack ! 813: ppoopp _s Pop a word from the stack ! 814: ppooppff Pop from stack into flags register ! 815: ppuusshh _m Push a word onto the stack ! 816: ppuusshh _s Push a word onto the stack ! 817: ppuusshhff Push flags register onto the stack ! 818: rrccllbb _a, $_1 Rotate left $1 times, byte ! 819: rrccllbb _a, _c_l Rotate left CL times, byte ! 820: rrccll _a, $_1 Rotate left $1 times, word ! 821: rrccll _a, _c_l Rotate left CL times, word ! 822: rrccrrbb _a, $_1 Rotate right $1 times, byte ! 823: rrccrrbb _a, _c_l Rotate right CL times, byte ! 824: rrccrr _a, $_1 Rotate right $1 times, word ! 825: rrccrr _a, _c_l Rotate right CL times, word ! 826: rreepp Repeat following string operation ! 827: rreeppee Find nonmatching bytes ! 828: rreeppnnee Repeat, not equal ! 829: rreeppnnzz Repeat, not equal ! 830: rreeppzz Repeat, equal ! 831: rreett Return from procedure ! 832: rroollbb _a, $_1 Rotate left, byte ! 833: rroollbb _a, _c_l Rotate left, byte ! 834: rrooll _a, $_1 Rotate left, word ! 835: rrooll _a, _c_l Rotate left, word ! 836: rroorrbb _a, $_1 Rotate right, byte ! 837: rroorrbb _a, _c_l Rotate right, byte ! 838: rroorr _a, $_1 Rotate right, word ! 839: rroorr _a, _c_l Rotate right, word ! 840: ssaahhff Store AH into flags ! 841: ssaallbb _a, $_1 Shift left, byte ! 842: ssaallbb _a, _c_l Shift left, byte ! 843: ssaall _a, $_1 Shift left, word ! 844: ssaall _a, _c_l Shift left, word ! 845: ssaarrbb _a, $_1 Shift right, byte ! 846: ssaarrbb _a, _c_l Shift right, byte ! 847: ssaarr _a, $_1 Shift right, word ! 848: ssaarr _a, _c_l Shift right, word ! 849: ssbbbbbb _r, _a Integer subtract with borrow, byte ! 850: ssbbbb _r, _a Integer subtract with borrow, word ! 851: ssbbbbbb _a, _r Integer subtract with borrow, byte ! 852: ssbbbb _a, _r Integer subtract with borrow, word ! 853: ssbbbbbb _a, $_e Integer subtract with borrow, byte ! 854: ! 855: ! 856: COHERENT Lexicon Page 13 ! 857: ! 858: ! 859: ! 860: ! 861: as Command as ! 862: ! 863: ! 864: ! 865: ssbbbb _a, $_e Integer subtract with borrow, word ! 866: ssccaassbb Compare string data, byte ! 867: ssccaass Compare string data, word ! 868: sshhllbb _a, $_1 Shift left, byte ! 869: sshhllbb _a, _c_l Shift left, byte ! 870: sshhll _a, $_1 Shift left, word ! 871: sshhll _a, _c_l Shift left, word ! 872: sshhrrbb _a, $_1 Shift right, byte ! 873: sshhrrbb _a, _c_l Shift right, byte ! 874: sshhrr _a, $_1 Shift right, word ! 875: sshhrr _a, _c_l Shift right, word ! 876: ssttcc Set carry flag ! 877: ssttdd Set direction flag ! 878: ssttii Set interrupt enable flag ! 879: ssttoossbb Store string data, byte ! 880: ssttooss Store string data, byte or word ! 881: ssttoossww Store string data, word ! 882: ssuubbbb _r, _a Integer subtraction, byte ! 883: ssuubb _r, _a Integer subtraction, word ! 884: ssuubbbb _a, _r Integer subtraction, byte ! 885: ssuubb _a, _r Integer subtraction, word ! 886: ssuubbbb _a, $_e Integer subtraction, byte ! 887: ssuubb _a, $_e Integer subtraction, word ! 888: tteessttbb _r, _a Logical compare, byte ! 889: tteesstt _r, _a Logical compare, word ! 890: tteessttbb _a, _r Logical compare, byte ! 891: tteesstt _a, _r Logical compare, word ! 892: tteessttbb _a, $_e Logical compare, byte ! 893: tteesstt _a, $_e Logical compare, word ! 894: wwaaiitt Wait until BUSY pin is inactive ! 895: xxccaallll _d, _d Far call, immediate four-byte address ! 896: xxcchhggbb _r, _a Exchange memory, byte ! 897: xxcchhgg _r, _a Exchange memory, word ! 898: xxiiccaallll Far call, address at EA double word ! 899: xxiijjmmpp Jump far, address at memory double word ! 900: xxjjmmpp _d, _d Jump far, immediate four-byte address ! 901: xxllaatt Table look-up translation ! 902: xxoorrbb _r, _a Logical exclusive OR, byte ! 903: xxoorr _r, _a Logical exclusive OR, word ! 904: xxoorrbb _a, _r Logical exclusive OR, byte ! 905: xxoorr _a, _r Logical exclusive OR, word ! 906: xxoorrbb _a, $_e Logical exclusive OR, byte ! 907: xxoorr _a, $_e Logical exclusive OR, word ! 908: xxrreett Return, intersegment ! 909: ! 910: ***** 80286 Instructions ***** ! 911: ! 912: The following instructions implement 80286-specific actions. ! 913: Programs that use them cannot be run on 8086-based machines. ! 914: ! 915: ppuusshhaa Push all general registers ! 916: ppooppaa Pop all general registers ! 917: ! 918: iinnssbb Input byte from port DX to ES:(DI) ! 919: iinnss Input word from port DX to ES:(DI) ! 920: ! 921: ! 922: COHERENT Lexicon Page 14 ! 923: ! 924: ! 925: ! 926: ! 927: as Command as ! 928: ! 929: ! 930: ! 931: oouuttssbb Output byte from port DX from ES:(DI) ! 932: oouuttss Output word from port DX from ES:(DI) ! 933: ! 934: eenntteerr $_e, $_e Make stack frame for procedure ! 935: lleeaavvee Tear down stack frame for procedure ! 936: ! 937: bboouunndd _r, _e Check array index against bounds ! 938: ! 939: ssllddtt _a Store Local Descriptor Table Register ! 940: ssttrr _a Store Task Register ! 941: llllddtt _a Load Local Descriptor Table Register ! 942: llttrr _a Load Task Register ! 943: vveerrrr _a Verify a segment for reading ! 944: vveerrww _a Verify a segment for writing ! 945: ! 946: ssggddtt _m Store Global Descriptor Table register ! 947: ssiiddtt _m Store Interrupt Descriptor Table register ! 948: llggddtt _m Load Global Descriptor Table register ! 949: lliiddtt _m Load Interrupt Descriptor Table register ! 950: ssmmssww _a Store Machine Status Word ! 951: llmmssww _a Load Machine Status Word ! 952: ! 953: llaarr _r,_a Load access rights byte ! 954: llssll _r,_a Load segment limit ! 955: ! 956: ccllttss Clear Task Switched Flag ! 957: aarrppll Adjust RPL field of Selector ! 958: ! 959: ppuusshh $_e Push sign extended byte ! 960: Also the $_1 forms become $_e on rol, rolb, ror, rorb, sal, salb, ! 961: shrb, shr, and shrb. This is because 8086 task of shifting and ! 962: rotating by an immediate value could only take an immediate value ! 963: of 1; however, on the 80286 the immediate value may be up to 31. ! 964: ! 965: ***** i8087 Op Codes ***** ! 966: ! 967: The assembler can also generate object files for use with the ! 968: i8087 mathematics co-processor. The following listing presents ! 969: the assembly language op codes for this feature. sstt00 indicates ! 970: floating point register 0 and sstt11 indicates any floating point ! 971: register but 0; dd is the same as in the above listing. ! 972: ! 973: ! 974: _d Direct address ! 975: _s_t_0Floating point register 0 ! 976: _s_t_1Any floating point register _e_x_c_e_p_t 0 ! 977: ! 978: ! 979: The following lists the i8087 instructions: ! 980: ffaabbss Absolute value ! 981: ffaadddd _s_t_0, _s_t_1Add real ! 982: ffaadddd _s_t_1, _s_t_0Add real ! 983: ffffaadddd _d Add real, float ! 984: ffddaadddd _d Add real, double ! 985: ffaaddddpp Add real and pop ! 986: ! 987: ! 988: COHERENT Lexicon Page 15 ! 989: ! 990: ! 991: ! 992: ! 993: as Command as ! 994: ! 995: ! 996: ! 997: ffaaddddpp _s_t, _s_t_0 Add real and pop ! 998: ffbblldd _d Load packed decimal (BCD) ! 999: ffbbssttpp _d Store packed decimal (BCD) and pop ! 1000: ffcchhss Change sign ! 1001: ffcclleexx Clear exception ! 1002: ffnncclleexx Clear exception ! 1003: ffccoomm Compare real ! 1004: ffffccoomm _d Compare real, float ! 1005: ffddccoomm _d Compare real, double ! 1006: ffccoommpp Compare real and pop ! 1007: ffccoommpp st1 Compare real and pop ! 1008: ffffccoommpp _d Compare real and pop, float ! 1009: ffddccoommpp _d Compare real and pop, double ! 1010: ffccoommpppp Compare real and pop twice ! 1011: ffddeeccssttpp Decrement stack pointer ! 1012: ffddiissii Disable interrupts ! 1013: ffnnddiissii Disable interrupts, no operands ! 1014: ffddiivv _s_t_0, _s_t_1Divide real ! 1015: ffddiivv _s_t_1, _s_t_0Divide real ! 1016: ffffddiivv _d Divide real, float ! 1017: ffddddiivv _d Divide real, double ! 1018: ffddiivvpp Divide real and pop ! 1019: ffddiivvpp st1 Divide real and pop ! 1020: ffddiivvrr _s_t_0, _s_t_1Divide real reversed ! 1021: ffddiivvrr _s_t_1, _s_t_0Divide real reversed ! 1022: ffffddiivvrr _d Divide real reversed, float ! 1023: ffddddiivvrr _d Divide real reversed, double ! 1024: ffddiivvrrpp Divide real reversed and pop ! 1025: ffddiivvrrpp _s_t_1 Divide real reversed and pop ! 1026: ffeennii Enable interrupts ! 1027: ffnneennii Enable interrupts, no operands ! 1028: ffffrreeee _s_t_1 Free register ! 1029: ffiiaadddd _d Integer add ! 1030: ffllaadddd _d Integer add, long ! 1031: ffiiccoomm _d Integer compare ! 1032: ffllccoomm _d Integer compare, long ! 1033: ffiiccoommpp _d Integer compare and pop ! 1034: ffllccoommpp _d Integer compare and pop, long ! 1035: ffiiddiivv _d Integer divide ! 1036: ffllddiivv _d Integer divide, long ! 1037: ffiiddiivvrr _d Integer divide reversed ! 1038: ffllddiivvrr _d Integer divide, long reversed ! 1039: ffiilldd _d Integer load ! 1040: fflllldd _d Integer load, long ! 1041: ffqqlldd _d Integer load, quad ! 1042: ffiimmuull _d Integer multiply ! 1043: ffllmmuull _d Integer multiply, long ! 1044: ffiinnccssttpp Increment stack pointer ! 1045: ffiinniitt Initialize processor ! 1046: ffnniinniitt Initialize processor ! 1047: ffiisstt _d Integer store ! 1048: ffllsstt _d Integer store, long ! 1049: ffiissttpp _d Integer store and pop ! 1050: ffllssttpp _d Integer store and pop, long ! 1051: ffqqssttpp _d Integer store and pop, quad ! 1052: ! 1053: ! 1054: COHERENT Lexicon Page 16 ! 1055: ! 1056: ! 1057: ! 1058: ! 1059: as Command as ! 1060: ! 1061: ! 1062: ! 1063: ffiissuubb _d Integer subtract ! 1064: ffllssuubb _d Integer subtract, long ! 1065: ffiissuubbrr _d Integer subtract reversed ! 1066: ffllssuubbrr _d Integer subtract reversed, long ! 1067: fflldd _s_t_1 Load real ! 1068: fffflldd _d Load real, float ! 1069: ffddlldd _d Load real, double ! 1070: ffttlldd _d Load real, temp ! 1071: ffllddccww _d Load control word ! 1072: ffllddeennvv _d Load environment ! 1073: ffllddllgg22 Load log(10)2 ! 1074: ffllddllnn22 Load log(e)2 ! 1075: ffllddll22ee Load log(2)e ! 1076: ffllddll22tt Load log(2)10 ! 1077: ffllddppii Load pi ! 1078: ffllddzz Load +0.0 ! 1079: fflldd11 Load +1.0 ! 1080: ffmmuull Multiply real ! 1081: ffmmuull _s_t_0, _s_t_1Multiply real ! 1082: ffffmmuull _s_t_1, _s_t_0Multiply real, float ! 1083: ffddmmuull _d Multiply real, double ! 1084: ffmmuullpp _d Multiply real and pop ! 1085: ffnnoopp st1 No operation ! 1086: ffppaattaann Partial arctangent ! 1087: ffpprreemm Partial remainder ! 1088: ffppttaann Partial tangent ! 1089: ffrrnnddiinntt Round to integer ! 1090: ffrrssttoorr _d Restore saved state ! 1091: ffssaavvee _d Save state ! 1092: ffnnssaavvee _d Save state ! 1093: ffssccaallee Scale ! 1094: ffsseettppmm Set protected mode ! 1095: ffssqqrrtt Square root ! 1096: ffsstt _s_t_1 Store real ! 1097: ffffsstt _d Store real, float ! 1098: ffddsstt _d Store real, double ! 1099: ffssttccww _d Store control word ! 1100: ffnnssttccww _d Store control word ! 1101: ffsstteennvv _d Store environment ! 1102: ffnnsstteennvv _d Store environment ! 1103: ffssttpp _s_t_1 Store real and pop ! 1104: ffffssttpp _d Store real and pop, float ! 1105: ffddssttpp _d Store real and pop, double ! 1106: ffttssttpp _d Store real and pop, temp ! 1107: ffssttssww _d Store status word ! 1108: ffnnssttssww _d Store status word ! 1109: ffssuubb _s_t_0, _s_t_1Subtract real ! 1110: ffssuubb _s_t_1, _s_t_0Subtract real ! 1111: ffffssuubb _d Subtract real, float ! 1112: ffddssuubb _d Subtract real, double ! 1113: ffssuubbpp Subtract real and pop ! 1114: ffssuubbpp _s_t_1 Subtract real and pop ! 1115: ffssuubbrr _d Subtract real reversed ! 1116: ffffssuubbrr _d Subtract real reversed, float ! 1117: ffddssuubbrr _d Subtract real reversed, double ! 1118: ! 1119: ! 1120: COHERENT Lexicon Page 17 ! 1121: ! 1122: ! 1123: ! 1124: ! 1125: as Command as ! 1126: ! 1127: ! 1128: ! 1129: ffssuubbrrpp Subtract real reversed and pop ! 1130: ffssuubbrrpp _s_t_1 Subtract real reversed and pop ! 1131: ffttsstt Test stack top against +0.0 ! 1132: ffwwaaiitt Wait while 8087 is busy ! 1133: ffxxaamm Examine stack top ! 1134: ffxxcchh _s_t_1 Exchange registers ! 1135: ffxxcchh Exchange registers ! 1136: ffxxttrraacctt Extract exponent and significance ! 1137: ffyyll22xx Y*log(2)X ! 1138: ffyyll22xxpp11 Y*log(2)(X+1) ! 1139: ! 1140: ***** C Compiler Conventions ***** ! 1141: ! 1142: as is often used to write small functions that perform tasks not ! 1143: easily or efficiently done in C. Such functions are intended to ! 1144: be called from a C program. As long as the assembly language ! 1145: source code follows compiler conventions, the assembler routine ! 1146: will be fully compatible with C functions. These conventions are ! 1147: (1) the names of external variables and (2) calling functions. ! 1148: ! 1149: ***** Naming Conventions ***** ! 1150: ! 1151: The C compiler appends an underline character `_' to the end of ! 1152: every external declared in a C source file. When referring to ! 1153: any external variable or function declared in a C source file, ! 1154: append an underscore to the name. In a similar manner, when ! 1155: defining a function or variable in an assembly language source ! 1156: file that is to be accessed from a C source file, append an un- ! 1157: derline character. ! 1158: ! 1159: ***** Function-Calling Conventions ***** ! 1160: ! 1161: Function-calling conventions deal with how arguments are passed ! 1162: to functions, how values are returned, and which registers are ! 1163: used for special purposes and must be protected. ! 1164: ! 1165: ***** Arguments ***** ! 1166: ! 1167: Function arguments are passed on the stack. They are pushed by ! 1168: the calling function, which also removes them when the called ! 1169: function returns. Looking at the declaration of the function, ! 1170: the order in which they are pushed onto the stack is from right ! 1171: to left; that is, the C compiler pushes the argument list in ! 1172: reverse order of declaration. The instruction call to jump to ! 1173: the function also pushes the return address, so that when the ! 1174: called routine gains control the first argument is found at of- ! 1175: fset 2 from the stack pointer. ! 1176: ! 1177: Integer and pointer arguments are word size, and are simply ! 1178: pushed with a push instruction. Characters, although byte size, ! 1179: are not passed as bytes. The C language requires that char ! 1180: variables be promoted to the type int before being passed. The ! 1181: promotion is signed or unsigned, depending on the type of the ! 1182: char variable. lloonnggs are pushed one word at a time; the higher- ! 1183: address word is pushed first. This ensures that the words of the ! 1184: ! 1185: ! 1186: COHERENT Lexicon Page 18 ! 1187: ! 1188: ! 1189: ! 1190: ! 1191: as Command as ! 1192: ! 1193: ! 1194: ! 1195: long are in the correct order on the stack, because the stack ! 1196: grows toward low-addressed memory. ! 1197: ! 1198: Passing ffllooaatts, ddoouubbllees, or structure arguments is more involved. ! 1199: C requires ffllooaatts to be promoted to and passed as ddoouubbllees, so ! 1200: this conversion must be performed first. ddoouubbllees and structures ! 1201: are passed so that as they sit on the stack, all bytes are in the ! 1202: correct order; this is analogous to the passing of lloonnggs. This ! 1203: means, for example, that ddoouubbllees may be pushed with four push ! 1204: word instructions, beginning with the highest addressed word in ! 1205: the 64-bit double, and ending with the lowest addressed word. ! 1206: ! 1207: If in doubt about how to apply any of this, try writing a simple ! 1208: C program that uses what you need, and compile it with the -vasm ! 1209: option to the cc command. This produces an assembly-language ! 1210: version of the C program, which can be studied to see exactly ! 1211: what the compiler does, and mimicked to good effect. ! 1212: ! 1213: ***** Return Values ***** ! 1214: ! 1215: ! 1216: Functions return values in various registers according to their ! 1217: type. iinntts and pointers are returned in the ax register. cchhaarrs ! 1218: are returned by first promoting them to iinntts and returning the ! 1219: result in the ax register; effectively, this means that cchhaarrs are ! 1220: returned in the al register. lloonnggs are returned in the dx:ax ! 1221: register pair, with the most significant word (also the high-ad- ! 1222: dress word) in the dx register, and the least significant word in ! 1223: the ax register. ! 1224: ! 1225: ffllooaatts, ddoouubbllees, and structures are returned in a more complex ! 1226: fashion. C requires ffllooaatts be returned as ddoouubbllees, so they are ! 1227: converted. ddoouubbllees are returned in a special eight-byte array ! 1228: named _ffppaacc (of course, in assembly language the name is _ffppaacc_). ! 1229: This array is defined by the compiler. In the event that a func- ! 1230: tion returns a structure, the contents of the structure are saved ! 1231: in memory, and the function returns a pointer to that structure ! 1232: in the ax register. The calling function then moves the bytes ! 1233: into the actual destination. ! 1234: ! 1235: Again, if in doubt about how to do this in assembly language, try ! 1236: compiling a function with assembly language output to see how the ! 1237: compiler does it. ! 1238: ! 1239: ***** Important Registers ***** ! 1240: ! 1241: Every function must preserve the value of the bp register, which ! 1242: is the caller's stack frame pointer. Also, the compiler uses the ! 1243: si and di registers for register variables, so they must be ! 1244: preserved. ! 1245: ! 1246: ***** Example of an Assembly Language Program ***** ! 1247: ! 1248: The following assembly language file, strchar.s defines a func- ! 1249: tion strchar that returns the number of occurrences of a charac- ! 1250: ! 1251: ! 1252: COHERENT Lexicon Page 19 ! 1253: ! 1254: ! 1255: ! 1256: ! 1257: as Command as ! 1258: ! 1259: ! 1260: ! 1261: ter in a string. ! 1262: ! 1263: ! 1264: FILE: strchar.s ! 1265: ! 1266: / ! 1267: / ! 1268: / Count and return the occurrences ! 1269: / of a character in a string. ! 1270: / ! 1271: / int ! 1272: / strchar(s, c) ! 1273: / char *s; ! 1274: / int c; ! 1275: / ! 1276: / ! 1277: ! 1278: ! 1279: ! 1280: .globl strchar_ / Make the name known externally. ! 1281: ! 1282: strchar_: ! 1283: push si / Standard C function ! 1284: push di / linkage. Save the ! 1285: push bp / si, di, and bp registers ! 1286: mov bp, sp / and set up new frame pointer. ! 1287: ! 1288: ! 1289: ! 1290: mov si, 8(bp) / String ptr -> si. ! 1291: mov bx, 10(bp) / Char -> bx (actually bl). ! 1292: sub ax, ax / Clear ax (count register). ! 1293: sub cx, cx / Clear cx. ! 1294: ! 1295: ! 1296: ! 1297: 0: movb cl, (si) / Get character from string. ! 1298: jcxz 2f / End of string? ! 1299: cmpb bl, cl / No. Do chars match? ! 1300: jnz 1f / No. ! 1301: inc ax / Yes. Increment count. ! 1302: ! 1303: ! 1304: ! 1305: 1: inc si / Bump string pointer ! 1306: jmp 0b / and loop again. ! 1307: ! 1308: ! 1309: ! 1310: 2: pop bp / Standard C return ! 1311: pop di / linkage. Restore ! 1312: pop si / saved registers and ! 1313: ret / go home. ! 1314: ! 1315: ! 1316: ! 1317: ! 1318: COHERENT Lexicon Page 20 ! 1319: ! 1320: ! 1321: ! 1322: ! 1323: as Command as ! 1324: ! 1325: ! 1326: ! 1327: ! 1328: The following C program, main.c uses strchar The assembly lan- ! 1329: guage listing that follows, main.s was produced from main.c by ! 1330: the -vasm option in cc. The listing has been edited, and com- ! 1331: ments added, to illustrate what is happening. ! 1332: ! 1333: ! 1334: FILE: main.c ! 1335: ! 1336: main() ! 1337: { ! 1338: int n; ! 1339: n = strchar("aardvark", 'a'); ! 1340: } ! 1341: ! 1342: ! 1343: ! 1344: FILE: main.s ! 1345: ! 1346: .shri / ``code'' program section. ! 1347: ! 1348: .globl main_ ! 1349: ! 1350: ! 1351: ! 1352: main_: ! 1353: ! 1354: .strn / ``string'' program section. ! 1355: ! 1356: ! 1357: ! 1358: L2: .byte 0x61 / This is the string ! 1359: .byte 0x61 / ``aardvark'' ! 1360: .byte 0x72 ! 1361: .byte 0x64 ! 1362: .byte 0x76 ! 1363: .byte 0x61 ! 1364: .byte 0x72 ! 1365: .byte 0x6B ! 1366: .byte 0x00 ! 1367: ! 1368: ! 1369: ! 1370: .shri / Back to ``code'' ! 1371: ! 1372: push si / Standard C function ! 1373: push di / linkage. Save registers, ! 1374: push bp / set up new frame pointer (bp), ! 1375: mov bp, sp / and make room on stack ! 1376: sub sp, $0x02 / for the auto int, ``n'' ! 1377: ! 1378: ! 1379: ! 1380: ! 1381: ! 1382: ! 1383: ! 1384: COHERENT Lexicon Page 21 ! 1385: ! 1386: ! 1387: ! 1388: ! 1389: as Command as ! 1390: ! 1391: ! 1392: ! 1393: mov ax, $0x61 / Push the ! 1394: push ax / character `a'. ! 1395: mov ax, $L2 / Push the address ! 1396: push ax / of the string ``aardvark'' ! 1397: call strchar_ / Function call. ! 1398: add sp, $0x04 / Remove args from stack. ! 1399: mov -0x02(bp), ax / Assign result to auto `n'. ! 1400: ! 1401: ! 1402: ! 1403: mov sp, bp / Standard C return ! 1404: pop bp / linkage. Adjust stack ! 1405: pop di / pointer, then restore ! 1406: pop si / registers and ! 1407: ret / go home. ! 1408: ! 1409: ! 1410: ***** Diagnostics ***** ! 1411: ! 1412: All errors detected by the assembler are reported on the screen ! 1413: as an error message that is tagged with a line number. If a sym- ! 1414: bol is associated with the error message (for example, if a sym- ! 1415: bol is undefined), then the symbol's name is also given. If more ! 1416: than one input file appears on the command line, error messages ! 1417: are tagged with the name of the source file. ! 1418: ! 1419: If a listing is generated, errors are reported on the listing in ! 1420: the same format, with the error flags at the left margin. The ! 1421: total number of errors is displayed on the screen at the end of ! 1422: the assembly. ! 1423: ! 1424: For a full listing of aass error messages, see the tutorial for the ! 1425: C compiler, which appears earlier in this manual. ! 1426: ! 1427: ***** See Also ***** ! 1428: ! 1429: cc, commands ! 1430: ! 1431: ! 1432: ! 1433: ! 1434: ! 1435: ! 1436: ! 1437: ! 1438: ! 1439: ! 1440: ! 1441: ! 1442: ! 1443: ! 1444: ! 1445: ! 1446: ! 1447: ! 1448: ! 1449: ! 1450: COHERENT Lexicon Page 22 ! 1451: ! 1452:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.