Difference between revisions of "Assembly Language"

From CDOT Wiki
Jump to: navigation, search
(Resources)
Line 1: Line 1:
 
[[Category:Computer Architecture]][[Category:Assembly Language]]
 
[[Category:Computer Architecture]][[Category:Assembly Language]]
''Assembly language'' is a [[Symbol|symbolic]] representation of [[Machine Language|machine language]]. It is therefore [[Portable|architecture-specific]].
+
''Assembly language'' is a [[Symbol|symbolic]] representation of [[Machine Language|machine language]]. It is therefore very [[Portable|architecture-specific]].
  
 
Each instruction is represented by a short mnemonic word such as "LDR" for ''Load Register'', "MOV" for ''move'', or "MUL" for ''multiply'', followed by (optional) arguments. The [[Addressing Mode|addressing mode]] is implied by the format of the arguments. Different [[Assembler|assemblers]] use slightly different syntax.
 
Each instruction is represented by a short mnemonic word such as "LDR" for ''Load Register'', "MOV" for ''move'', or "MUL" for ''multiply'', followed by (optional) arguments. The [[Addressing Mode|addressing mode]] is implied by the format of the arguments. Different [[Assembler|assemblers]] use slightly different syntax.
Line 7: Line 7:
  
 
=== x86 ===
 
=== x86 ===
 +
 +
Here is a "Hello, World!" program written for an x86_64 Linux system using the [https://sourceware.org/binutils/docs/as/ GNU Assembler (gas/as)] syntax (which is the main assembler used in open source projects such as the Linux kernel, as well as the [[SPO600]] course):
 +
 +
.text
 +
.globl _start
 +
_start:
 +
    mov $len, %edx    /* file descriptor: 1 is stdout */
 +
    mov $msg, %ecx    /* message location (memory address) */
 +
    mov $1, %ebx      /* message length (bytes) */
 +
    mov $4, %eax      /* write is syscall #4 */
 +
    int $0x80          /* invoke syscall */
 +
 +
    mov $0, %ebx      /* exit status: 0 (good) */
 +
    mov $1, %eax      /* kernel syscall number: 1 is sys_exit */
 +
    int $0x80          /* invoke syscall */
 +
 +
.data
 +
msg:
 +
    .ascii "Hello, World!\n"
 +
    len = . - msg
  
 
Here is a "Hello, World!" program in x86 assembler for a Linux system, using the [http://www.nasm.us/xdoc/2.11/html/nasmdoc1.html#section-1.1 Nasm] syntax:
 
Here is a "Hello, World!" program in x86 assembler for a Linux system, using the [http://www.nasm.us/xdoc/2.11/html/nasmdoc1.html#section-1.1 Nasm] syntax:
Line 29: Line 49:
 
  len    equ    $ - msg
 
  len    equ    $ - msg
  
Here is the same program with [https://sourceware.org/binutils/docs/as/ GNU Assembler (gas/as)] syntax:
 
  
.text
+
Notice that the order of the arguments in some lines is reversed between the two assemblers, and the prefixes to symbols and values also change.
.globl _start
 
_start:
 
    mov $len, %edx    /* file descriptor: 1 is stdout */
 
    mov $msg, %ecx    /* message location (memory address) */
 
    mov $1, %ebx      /* message length (bytes) */
 
    mov $4, %eax      /* write is syscall #4 */
 
    int $0x80          /* invoke syscall */
 
 
    mov $0, %ebx      /* exit status: 0 (good) */
 
    mov $1, %eax      /* kernel syscall number: 1 is sys_exit */
 
    int $0x80          /* invoke syscall */
 
 
.data
 
msg:
 
    .ascii "Hello, World!\n"
 
    len = . - msg
 
  
Notice that the order of the arguments in some lines is reversed between the two assemblers, and the prefixes to symbols and values also change.
 
  
 
=== ARM (32-bit) ===
 
=== ARM (32-bit) ===
Line 73: Line 75:
 
       .ascii      "Hello, world!\n"
 
       .ascii      "Hello, world!\n"
 
       len = . - msg
 
       len = . - msg
 +
 +
 +
=== ARM (64-bit) - AArch64 ===
 +
 +
This is also in [https://sourceware.org/binutils/docs/as/ GNU Assembler (gas/as)] syntax:
 +
 +
.text
 +
.globl _start
 +
_start:
 +
 +
mov    x0, 1          /* file descriptor: 1 is stdout */
 +
adr    x1, msg  /* message location (memory address) */
 +
  mov    x2, len  /* message length (bytes) */
 +
 
 +
  mov    x8, 64    /* write is syscall #64 */
 +
svc    0          /* invoke syscall */
 +
 +
mov    x0, 0    /* status -> 0 */
 +
mov    x8, 93    /* exit is syscall #93 */
 +
svc    0          /* invoke syscall */
 +
 +
.data
 +
msg: .ascii      "Hello, world!\n"
 +
len= . - msg
 +
 +
 +
=== 6502 ===
 +
 +
Here is the same "Hello World" program in [[6502]] assembler as used in the [[6502 Emulator]]:
 +
 +
define SCINIT $ff81 ; initialize/clear screen
 +
define CHROUT $ffd2 ; output character to screen
 +
 +
JSR SCINIT ; clear screen
 +
LDY #$00 ; set Y index to zero
 +
 +
loop: LDA msg,Y ; get a character
 +
BEQ done ; quit if character is null
 +
JSR CHROUT ; output the character
 +
INY ; increment index
 +
JMP loop ; get next character
 +
 +
done: BRK ; break (stop program)
 +
 +
msg:
 +
DCB "H","e","l","l","o",$2C,$20
 +
DCB "W","o","r","l","d","!",$0d, $00
 +
  
 
== Resources ==
 
== Resources ==

Revision as of 13:00, 12 September 2022

Assembly language is a symbolic representation of machine language. It is therefore very architecture-specific.

Each instruction is represented by a short mnemonic word such as "LDR" for Load Register, "MOV" for move, or "MUL" for multiply, followed by (optional) arguments. The addressing mode is implied by the format of the arguments. Different assemblers use slightly different syntax.

Examples

x86

Here is a "Hello, World!" program written for an x86_64 Linux system using the GNU Assembler (gas/as) syntax (which is the main assembler used in open source projects such as the Linux kernel, as well as the SPO600 course):

.text
.globl _start
_start:
    mov $len, %edx     /* file descriptor: 1 is stdout */ 
    mov $msg, %ecx     /* message location (memory address) */
    mov $1, %ebx       /* message length (bytes) */
    mov $4, %eax       /* write is syscall #4 */
    int $0x80          /* invoke syscall */

    mov $0, %ebx       /* exit status: 0 (good) */
    mov $1, %eax       /* kernel syscall number: 1 is sys_exit */
    int $0x80          /* invoke syscall */

.data
msg:
    .ascii "Hello, World!\n"
    len = . - msg

Here is a "Hello, World!" program in x86 assembler for a Linux system, using the Nasm syntax:

section    .text
global    _start

_start:
    mov    edx,len          ; message length (bytes)
    mov    ecx,msg          ; message location (memory address)
    mov    ebx,1            ; file descriptor: 1 is stdout
    mov    eax,4            ; kernel syscall number: 4 is sys_write
    int    0x80             ; invoke syscall

    mov    ebx,0            ; exit status: 0 (good)
    mov    eax,1            ; kernel syscall number: 1 is sys_exit
    int    0x80             ; invoke syscall

section    .rodata

msg    db    'Hello, world!\n'
len    equ    $ - msg


Notice that the order of the arguments in some lines is reversed between the two assemblers, and the prefixes to symbols and values also change.


ARM (32-bit)

This is written in GNU Assembler (gas/as) syntax:

.text
.globl _start
_start:

     mov     %r0, $1     /* file descriptor: 1 is stdout */
     ldr     %r1, =msg   /* message location (memory address) */
     ldr     %r2, =len   /* message length (bytes) */
     mov     %r7, $4     /* write is syscall #4 */
     swi     $0          /* invoke syscall */

     mov     %r0, $0     /* exit status: 0 (good) */
     mov     %r7, $1     /* kernel syscall number: 1 is sys_exit */
     swi     $0          /* invoke syscall */

.data
msg:
     .ascii      "Hello, world!\n"
     len = . - msg


ARM (64-bit) - AArch64

This is also in GNU Assembler (gas/as) syntax:

.text
.globl _start
_start:

	mov     x0, 1           /* file descriptor: 1 is stdout */
	adr     x1, msg   	/* message location (memory address) */
 	mov     x2, len   	/* message length (bytes) */
 
 	mov     x8, 64     	/* write is syscall #64 */
	svc     0          	/* invoke syscall */

mov x0, 0 /* status -> 0 */ mov x8, 93 /* exit is syscall #93 */ svc 0 /* invoke syscall */

.data
msg: 	.ascii      "Hello, world!\n"
len= 	. - msg


6502

Here is the same "Hello World" program in 6502 assembler as used in the 6502 Emulator:

define SCINIT $ff81 ; initialize/clear screen
define CHROUT $ffd2 ; output character to screen

	JSR SCINIT	; clear screen
	LDY #$00	; set Y index to zero

loop:	LDA msg,Y	; get a character
	BEQ done	; quit if character is null
	JSR CHROUT	; output the character
	INY		; increment index
	JMP loop	; get next character

done:	BRK		; break (stop program)

msg:	
	DCB "H","e","l","l","o",$2C,$20
	DCB "W","o","r","l","d","!",$0d, $00


Resources