Skip to content

Instantly share code, notes, and snippets.

@guihao-liang
Last active November 27, 2024 22:28
Show Gist options
  • Select an option

  • Save guihao-liang/bd70ed59ec87953e74538c8c526c0d8e to your computer and use it in GitHub Desktop.

Select an option

Save guihao-liang/bd70ed59ec87953e74538c8c526c0d8e to your computer and use it in GitHub Desktop.
asm examples for for mach-o; referenced from https://cs.lmu.edu/~ray/notes/nasmtutorial/
; ----------------------------------------------------------------------------------------
;
; In macOS land, C functions (or any function that is exported from one module to another, really)
; must be prefixed with underscores.
;
; The call stack must be aligned on a 16-byte boundary.
;
; And when accessing named variables, a `rel` prefix is required.
;
; nasm -fmacho64 hello_with_c.asm && cc hello_with_c.o && ./a.out
; ----------------------------------------------------------------------------------------
global _main
extern _puts
section .text
_main: push rbx ; Call stack must be aligned
lea rdi, [rel message] ; First argument is address of message
call _puts ; puts(message)
pop rbx ; Fix up stack before returning
ret
section .data
message: db "Hello, World!", 0 ; C strings need a zero byte at the end
; ----------------------------------------------------------------------------------------
; NASM syntax
;
; modified from: https://cs.lmu.edu/~ray/notes/nasmtutorial/
;
; For Linux:
;
; nasm -felf64 -o hello_64_n.o hello_64.asm
; ld hello_64_n.o && ./a.out
;
; For Mac:
;
; nasm -f macho64 -o hello_64_n.o hello_64.asm
; ld hello_64_n.o -e _start -o hello_64_n.out -lSystem
;
; ----------------------------------------------------------------------------------------
global _start
section .text
_start: mov rax, 0x2000004 ; system call for write
mov rdi, 1 ; file handle 1 is stdout
mov rsi, msg ; address of string to output
; lea rsi, [rel msg] ; allow PIE
mov rdx, msg.len ; number of bytes
syscall ; invoke operating system to do the write
mov rax, 0x2000001 ; system call for exit
xor rdi, rdi ; exit code 0
syscall ; invoke operating system to exit
section .data
msg: db "Hello, World!", 10 ; note the newline at the end
.len: equ $ - msg
# ---------------------------------------------------------------------------
# GAS syntax
#
# referenced from:
# http://www.idryman.org/blog/2014/12/02/writing-64-bit-assembly-on-mac-os-x/
#
# file: hello_64.s
#
# as hello_64.s -o hello_64_g.o
# ld hello_64_g.o -e _main -o hello_64_g.out -lSystem
#
# ---------------------------------------------------------------------------
.section __DATA,__data
str:
.ascii "Hello, World!\n"
.len = . - str
.section __TEXT,__text
.globl _main
_main:
mov $0x2000004, %eax # preparing system call 4
mov $1, %rdi # STDOUT file descriptor is 1
# GOT needs to be access from the instruction pointer %rip
mov str@GOTPCREL(%rip), %rsi # The value to print
# alternative
# lea str(%rip), %rsi # take the address
mov $.len, %rdx # the size of the value to print
syscall
xor %rdi, %rdi
mov $0x2000001, %rax # exit 0
syscall
; ----------------------------------------------------------------------------------------
; https://cs.lmu.edu/~ray/notes/nasmtutorial/
;
; nasm -fmacho64 triangle_with_bss.asm && ld triangle_with_bss.o -lSystem && ./a.out
; ----------------------------------------------------------------------------------------
global _main
section .text
_main:
mov rdx, output ; rdx holds address of next byte to write
mov r8, 1 ; initial line length
mov r9, 0 ; number of stars written on line so far
line:
mov byte [rdx], '*' ; write single star
inc rdx ; advance pointer to next cell to write
inc r9 ; "count" number so far on line
cmp r9, r8 ; did we reach the number of stars for this line?
jne line ; not yet, keep writing on this line
lineDone:
mov byte [rdx], 10 ; write a new line char
inc rdx ; and move pointer to where next char goes
inc r8 ; next line will be one char longer
mov r9, 0 ; reset count of stars written on this line
cmp r8, maxlines ; wait, did we already finish the last line?
jng line ; if not, begin writing this line
done:
mov rax, 0x02000004 ; system call for write
mov rdi, 1 ; file handle 1 is stdout
mov rsi, output ; address of string to output
mov rdx, dataSize ; number of bytes
syscall ; invoke operating system to do the write
mov rax, 0x02000001 ; system call for exit
xor rdi, rdi ; exit code 0
syscall ; invoke operating system to exit
section .bss
maxlines equ 8
dataSize equ 44
output: resb dataSize
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment