clean up some stuff

This commit is contained in:
andromeda
2026-03-25 21:14:34 +01:00
parent 31a438d1ee
commit 2960c1b795
3 changed files with 146 additions and 175 deletions

View File

@@ -160,7 +160,7 @@ the `type` hex digit is defined as the following:
| hex | meaning | examples | | hex | meaning | examples |
|-----|----------|-| |-----|----------|-|
| 0x0 | ignored | `; this entire comment is 1 token` | | 0x0 | ignored | |
| 0x1 | operator | `mov`, `hlt` | | 0x1 | operator | `mov`, `hlt` |
| 0x2 | register | `rsp`, `al` | | 0x2 | register | `rsp`, `al` |
| 0xF | unknown | any token ID not represented in the lookup table | | 0xF | unknown | any token ID not represented in the lookup table |

View File

@@ -7,8 +7,6 @@ TEST_ARENA_SIZE equ 0x1000 ; maximum size tests can use
TOKEN_TABLE_ADDR equ 0x00060000 ; address the token table is loaded at TOKEN_TABLE_ADDR equ 0x00060000 ; address the token table is loaded at
TOKEN_TABLE_SIZE equ 0x1000 ; max length of table TOKEN_TABLE_SIZE equ 0x1000 ; max length of table
TOKEN_TABLE_ENTRY_SIZE equ 2 ; size of token table entry; things may break
; if this ever changes
OUTPUT_ADDR equ 0x00070000 ; address of outputed binary OUTPUT_ADDR equ 0x00070000 ; address of outputed binary
OUTPUT_SIZE equ 0x1000 ; max length of outputed binary OUTPUT_SIZE equ 0x1000 ; max length of outputed binary
@@ -49,11 +47,14 @@ start:
mov rdi, program ; -> program mov rdi, program ; -> program
mov rsi, [program.size] ; = size of program mov rsi, [program.size] ; = size of program
call tokenise call tokenise
; rax = number of tokens processed ; rax = number of tokens in token table
mov rdi, rax mov rdi, rax
push rdi push rdi
call clear_output_arena call clear_output_arena
pop rdi
pop rdi ; rdi = number of tokens in token table
call assemble call assemble
jmp halt jmp halt
@@ -64,8 +65,6 @@ start:
; ------------------------------------------------------------------------------ ; ------------------------------------------------------------------------------
; assemble ; assemble
; TODO write tests
; TODO make it work :/ putting the cart before the horse
; ;
; description: ; description:
; assembles the program from tokens located at TOKEN_TABLE_ADDR into a flat ; assembles the program from tokens located at TOKEN_TABLE_ADDR into a flat
@@ -85,20 +84,28 @@ start:
; ------------------------------------------------------------------------------ ; ------------------------------------------------------------------------------
assemble: assemble:
xor eax, eax ; rax = number of tokens processed ; TODO deal with src=imm and src=imm8
mov [.tokens_total], edi ; rdi = number of tokens in table xor eax, eax
mov [.tokens_processed], eax ; eax = number of tokens processed
mov [.tokens_total], edi ; edi = total number of tokens in table
.loop: .loop:
xor edi, edi call .get_next_tte
mov di, [rax * TOKEN_TABLE_ENTRY_SIZE + TOKEN_TABLE_ADDR] ; next tte ; di = tte
call get_tte_type
; al = type
cmp al, 0x1 ; check if next tte is an operator
je .operator ; if so, handle
jmp .unexpected_token ; otherwise, fail
; di = tte of operator
.operator: ; if next tte's type is an operator: .operator: ; if next tte's type is an operator:
push rdi
; di = tte of operator ; di = tte of operator
call get_tte_typed_metadata call get_tte_typed_metadata
; al = tte typed metadata ; al = tte typed metadata
pop rdi
cmp al, UNRECOGNISED_ID_METADATA ; make sure token has metadata on record
je .unexpected_token ; if not, fail
and al, 11b ; mask for # operands and al, 11b ; mask for # operands
@@ -111,39 +118,25 @@ assemble:
cmp al, 2 ; check if operator has two operands cmp al, 2 ; check if operator has two operands
je .operator_2 ; if so, handle case of two operands je .operator_2 ; if so, handle case of two operands
jmp .unexpected_token ; TODO actually check operator type or not first jmp .unexpected_token
; if get_tte_typed_metadata happens to return 0, 1,
; or 2 on a non-operator, it doesn't get caught
; di = tte of operator
.operator_0: .operator_0:
push rsi
mov rsi, .msg_operator_0 mov rsi, .msg_operator_0
call print.debug call print.debug
pop rsi
push rdi
push rsi
; di = tte of operator ; di = tte of operator
mov sil, 0b ; standard opcode mov sil, 0b ; opcode
call get_opcode call get_opcode
; al = opcode ; al = opcode
; dl = op flag (none) ; dl = 0x00
call .output_byte call .output_byte
pop rsi
pop rdi
jmp .loop_next_token jmp .loop_next_token
; di = tte of operator
.operator_1: .operator_1:
push rsi
mov rsi, .msg_operator_1 mov rsi, .msg_operator_1
call print.debug call print.debug
pop rsi
push rdi
push rsi
; di = tte of operator ; di = tte of operator
mov sil, 0b ; dst=r/m mov sil, 0b ; dst=r/m
call get_opcode call get_opcode
@@ -152,13 +145,10 @@ assemble:
push rdx push rdx
call .output_byte call .output_byte
pop rdx ; dl = op flag pop rdx ; dl = op flag
pop rsi
pop rdi ; di = tte of operator
call .next_token call .next_token
jge .break jge .break
xor edi, edi call .get_next_tte
mov di, [rax * TOKEN_TABLE_ENTRY_SIZE + TOKEN_TABLE_ADDR] ; di = next tte
push rdi push rdi
and di, 0xFF00 and di, 0xFF00
@@ -178,23 +168,19 @@ assemble:
jmp .loop_next_token jmp .loop_next_token
.operator_1_memory: .operator_1_memory:
push rsi
mov rsi, .msg_operator_1_memory mov rsi, .msg_operator_1_memory
call print.debug call print.debug
pop rsi
jmp .unsupported_memory_access jmp .unsupported_memory_access
.operator_1_register: .operator_1_register:
push rsi
mov rsi, .msg_operator_1_register mov rsi, .msg_operator_1_register
call print.debug call print.debug
pop rsi
mov si, di ; si = `R/M` tte mov si, di ; si = `R/M` tte
and edx, 0xFF and edx, 0xFF
or dx, 0xFE00 ; pass di as direct value or edx, 0xFE00 ; pass di as direct value
mov di, dx ; di = op flag mov edi, edx ; di = op flag
mov dl, 11b ; dl = mod bits mov edx, 11b ; dl = mod bits
call get_ModRM call get_ModRM
; al = Mod R/M byte ; al = Mod R/M byte
call .output_byte call .output_byte
@@ -202,17 +188,14 @@ assemble:
jmp .loop_next_token jmp .loop_next_token
.operator_2: .operator_2:
push rsi
mov rsi, .msg_operator_2 mov rsi, .msg_operator_2
call print.debug call print.debug
pop rsi
mov cx, di ; cx = tte of operator mov cx, di ; cx = tte of operator
call .next_token call .next_token
jge .break jge .break
xor edi, edi call .get_next_tte
mov di, [rax * TOKEN_TABLE_ENTRY_SIZE + TOKEN_TABLE_ADDR] ; di = next tte
push rdi push rdi
and di, 0xFF00 and di, 0xFF00
@@ -232,57 +215,49 @@ assemble:
jmp .loop_next_token jmp .loop_next_token
.operator_2_memory: .operator_2_memory:
push rsi
mov rsi, .msg_operator_2_memory mov rsi, .msg_operator_2_memory
call print.debug call print.debug
pop rsi
cmp di, 0x1000 ; check if token is addressing a register cmp di, 0x1000 ; check if token is addressing a register
jne .unsupported_memory_access ; if not, unsupported :/ jne .unsupported_memory_access ; if not, unsupported
mov edi, ecx ; di = tte of operator
push rdi xor esi, esi ; dst=r/m; src=r
mov di, cx ; di = tte of operator
mov sil, 0 ; dst = r/m
call get_opcode call get_opcode
; al = opcode ; al = opcode
; dl = op flag ; dl = op flag
; TODO act accordingly if the op flag is present
call .output_byte call .output_byte
pop rdi
call .next_token call .next_token
jge .break jge .break
xor edi, edi call .get_next_tte
mov di, [rax * TOKEN_TABLE_ENTRY_SIZE + TOKEN_TABLE_ADDR] ; di = next tte
mov si, di ; si = dst tte mov si, di ; si = dst register tte
call .next_token call .next_token
jge .break jge .break
xor edi, edi call .get_next_tte
mov di, [rax * TOKEN_TABLE_ENTRY_SIZE + TOKEN_TABLE_ADDR] ; di = next tte
push rdi push rdi
and di, 0xFF00 and di, 0xFF00
cmp di, 0x1000 ; check if token is a memory address cmp di, 0x1000 ; check if token is a memory address
pop rdi ; di = next tte pop rdi ; di = next tte
je .unsupported_memory_access ; no case of *],[* in asm je .unsupported_memory_access ; if so, fail; no case of *],[* in asm
; di = next tte ; di = next tte
call get_tte_type call get_tte_type
; al = type of token ; al = type of token
cmp al, 0x02 cmp al, 0x02 ; check if token is a register
je .operator_2_memory_register je .operator_2_memory_register ; if so, handle
jmp .loop_next_token jmp .unexpected_token
.operator_2_memory_register: .operator_2_memory_register:
push rsi push rsi
mov rsi, .msg_operator_2_memory_register mov rsi, .msg_operator_2_memory_register
call print.debug call print.debug
pop rsi pop rsi ; si = r/m
; si = r/m; dst tte ; si = r/m; dst tte
; di = reg; src tte ; di = reg; src tte
@@ -294,10 +269,8 @@ assemble:
jmp .loop_next_token jmp .loop_next_token
.operator_2_register: .operator_2_register:
push rsi
mov rsi, .msg_operator_2_register mov rsi, .msg_operator_2_register
call print.debug call print.debug
pop rsi
push rdi push rdi
mov di, cx ; di = tte of operator mov di, cx ; di = tte of operator
@@ -307,14 +280,13 @@ assemble:
; dl = op flag ; dl = op flag
; TODO do something if the op flag is present ; TODO do something if the op flag is present
call .output_byte call .output_byte
pop rdi pop rdi ; di = dst tte
mov si, di ; si = dst tte mov si, di ; si = dst tte
call .next_token call .next_token
jge .break jge .break
xor edi, edi call .get_next_tte
mov di, [rax * TOKEN_TABLE_ENTRY_SIZE + TOKEN_TABLE_ADDR] ; di = next tte
push rdi push rdi
and di, 0xFF00 and di, 0xFF00
@@ -326,31 +298,30 @@ assemble:
call get_tte_type call get_tte_type
; al = type of token ; al = type of token
cmp al, 0x02 cmp al, 0x02 ; check if token is a register
je .operator_2_register_register je .operator_2_register_register ; if so, handle
jmp .loop_next_token jmp .unexpected_token
.operator_2_register_memory: .operator_2_register_memory:
push rsi push rsi
mov rsi, .msg_operator_2_register_memory mov rsi, .msg_operator_2_register_memory
call print.debug call print.debug
pop rsi pop rsi ; si = dst tte
cmp di, 0x1000 ; check if token is addressing to a register cmp di, 0x1000 ; check if token is addressing to a register
jne .unsupported_memory_access ; if not, unsupported :/ jne .unsupported_memory_access ; if not, unsupported
call .next_token call .next_token
jge .break jge .break
xor edi, edi call .get_next_tte
mov di, [rax * TOKEN_TABLE_ENTRY_SIZE + TOKEN_TABLE_ADDR] ; di = next tte
; si = `R/M` tte ; si = r/m; dst tte
; di = `reg` tte ; di = reg; src tte
push rsi push rsi
mov si, di mov esi, edi ; si = reg; src tte
pop rdi pop rdi ; di = r/m; dst tte
mov dl, 00b ; dl = mod bits mov edx, 00b ; dl = mod bits
call get_ModRM call get_ModRM
; al = Mod R/M byte ; al = Mod R/M byte
call .output_byte call .output_byte
@@ -358,15 +329,13 @@ assemble:
jmp .loop_next_token jmp .loop_next_token
.operator_2_register_register: .operator_2_register_register:
push rsi
mov rsi, .msg_operator_2_register_register mov rsi, .msg_operator_2_register_register
call print.debug call print.debug
pop rsi
push rsi push rsi
mov si, di ; si = reg; src tte mov esi, edi ; si = reg; src tte
pop rdi ; di = r/m; dst tte pop rdi ; di = r/m; dst tte
mov dl, 11b ; dl = mod bits mov edx, 11b ; dl = mod bits
call get_ModRM call get_ModRM
; al = Mod R/M byte ; al = Mod R/M byte
call .output_byte call .output_byte
@@ -402,6 +371,13 @@ assemble:
cmp eax, edi cmp eax, edi
ret ret
; eax = current entry index in token table
; returns di = next tte
.get_next_tte:
xor edi, edi
mov di, [eax * 2 + TOKEN_TABLE_ADDR]
ret
.tokens_processed dd 0 .tokens_processed dd 0
.tokens_total dd 0 .tokens_total dd 0
@@ -444,27 +420,27 @@ assemble:
; ------------------------------------------------------------------------------ ; ------------------------------------------------------------------------------
get_tte_type: get_tte_type:
and rdi, 0xFFFF ; mask input so it behaves as expected and edi, 0xFFFF ; di = token table entry
xor eax, eax xor eax, eax ; eax = tokens.by_id index
.loop: .loop:
cmp rax, (tokens.by_id_end - tokens.by_id) / 4 ; make sure it's still in range cmp eax, (tokens.by_id_end - tokens.by_id) / 4 ; index range check
jg .not_found jg .not_found
mov cx, [tokens.by_id + rax * 4] ; next entry in tokens.by_id mov cx, [tokens.by_id + eax * 4] ; next entry in tokens.by_id
cmp cx, di cmp cx, di
je .found je .found
inc rax inc eax
jmp .loop jmp .loop
.not_found: .not_found:
mov al, UNRECOGNISED_ID_TYPE mov eax, UNRECOGNISED_ID_TYPE
and ax, 0xF ; mask as expected and eax, 0xF
ret ret
.found: .found:
mov al, [2 + tokens.by_id + rax * 4] mov al, [2 + tokens.by_id + eax * 4]
and ax, 0xF ; mask as expected and eax, 0xF ; mask as expected
ret ret
; ------------------------------------------------------------------------------ ; ------------------------------------------------------------------------------
@@ -483,27 +459,26 @@ get_tte_type:
; ------------------------------------------------------------------------------ ; ------------------------------------------------------------------------------
get_tte_typed_metadata: get_tte_typed_metadata:
and rdi, 0xFFFF ; mask input so it behaves as expected and edi, 0xFFFF ; di = token table entry
xor eax, eax xor eax, eax ; eax = tokens.by_id index
.loop: .loop:
cmp rax, (tokens.by_id_end - tokens.by_id) / 4 ; make sure it's still in range cmp eax, (tokens.by_id_end - tokens.by_id) / 4 ; index range check
jg .not_found jg .not_found
mov cx, [tokens.by_id + rax * 4] ; next entry in tokens.by_id mov cx, [tokens.by_id + eax * 4] ; next entry in tokens.by_id
cmp cx, di cmp cx, di
je .found je .found
inc rax inc eax
jmp .loop jmp .loop
.not_found: .not_found:
xor eax, eax mov eax, UNRECOGNISED_ID_METADATA
mov al, UNRECOGNISED_ID_METADATA
ret ret
.found: .found:
mov al, [3 + tokens.by_id + rax * 4] mov al, [3 + tokens.by_id + eax * 4]
and rax, 0xFF and eax, 0xFF
ret ret
; ------------------------------------------------------------------------------ ; ------------------------------------------------------------------------------
@@ -524,11 +499,14 @@ get_tte_typed_metadata:
get_ModRM: get_ModRM:
push rbx push rbx
and dl, 11b ; mask for mod bits and edi, 0xFFFF ; di = token table entry `reg`
shl dl, 6 and esi, 0xFFFF ; si = token table entry `R/M`
and edx, 11b ; dl = mod bits
shl edx, 6 ; and position
push rdi push rdi
shr di, 8 shr edi, 8
cmp dil, 0xFE cmp dil, 0xFE
pop rdi pop rdi
je .pass_di_as_op_flag je .pass_di_as_op_flag
@@ -541,25 +519,25 @@ get_ModRM:
jmp .continue jmp .continue
.pass_di_as_op_flag: .pass_di_as_op_flag:
mov bl, dil ; bl = op flag mov ebx, edi ; bl = op flag
and bl, 111b ; mask and ebx, 111b
.continue: .continue:
shl bl, 3 shl ebx, 3
mov rdi, rsi ; do the other one mov edi, esi ; do the other one
; di = tte ; di = tte
call get_reg_bits call get_reg_bits
; al = reg bits ; al = reg bits
mov cl, al mov ecx, eax
xor eax, eax xor eax, eax
or al, dl ; mod bits or eax, edx ; mod bits
or al, bl ; reg bits or eax, ebx ; reg bits
or al, cl ; R/M bits or eax, ecx ; R/M bits
and rax, 0xFF ; mask for byte and eax, 0xFF ; mask for byte
pop rbx pop rbx
ret ret
@@ -581,49 +559,45 @@ get_ModRM:
; ------------------------------------------------------------------------------ ; ------------------------------------------------------------------------------
get_opcode: get_opcode:
and rdi, 0xFFFF and edi, 0xFFFF ; di = token table entry
add rsi, 2 add esi, 2
and rsi, 111b and esi, 111b ; offset within opcode entry
sub rsi, 2 sub esi, 2 ; between 0 and 5
xor eax, eax xor eax, eax ; eax = opcodes.by_id index
.loop: .loop:
cmp rax, (opcodes.by_id_end - opcodes.by_id) / 16 ; make sure it's still in range cmp eax, (opcodes.by_id_end - opcodes.by_id) / 16 ; make sure it's still in range
jg .not_found jg .not_found
shl rax, 4 shl eax, 4
mov cx, [opcodes.by_id + rax] ; next entry in opcodes.by_id mov cx, [opcodes.by_id + eax] ; next entry in opcodes.by_id
shr rax, 4 shr eax, 4
cmp cx, di cmp cx, di
je .found je .found
inc rax inc eax
jmp .loop jmp .loop
.not_found: .not_found:
xor eax, eax xor eax, eax
mov al, UNRECOGNISED_ID_OPCODE mov eax, UNRECOGNISED_ID_OPCODE
ret ret
.found: .found:
shl rax, 4 shl eax, 4
push rsi push rsi
shr rsi, 1 shr esi, 1
mov dl, [rsi + 8 + opcodes.by_id + rax] mov dl, [esi + 8 + opcodes.by_id + eax]
pop rsi pop rsi
push rsi test esi, 1 ; check if offset is odd
and rsi, 1 jz .found_continue
cmp esi, 1 ; check if offset is odd shr edx, 4 ; if so, upper part of dl byte
pop rsi
jne .found_continue
shr dl, 4 ; if so, actually 1 further on dl byte
.found_continue: .found_continue:
mov al, [rsi + 2 + opcodes.by_id + rax] mov al, [esi + 2 + opcodes.by_id + eax]
and rax, 0xFF ; mask and eax, 0xFF
and rdx, 0x0F ; mask and edx, 0x0F
ret ret
; ------------------------------------------------------------------------------ ; ------------------------------------------------------------------------------
@@ -644,8 +618,8 @@ get_reg_bits:
; di = tte ; di = tte
call get_tte_typed_metadata call get_tte_typed_metadata
; al = typed metadata ; al = typed metadata
shr al, 2 ; discard type data shr eax, 2 ; discard type data
and al, 111b ; mask and eax, 111b ; mask
ret ret
; ------------------------------------------------------------------------------ ; ------------------------------------------------------------------------------
@@ -823,7 +797,7 @@ tokenise:
pop rdi ; rdi = byte counter pop rdi ; rdi = byte counter
pop rax ; rax = tokens processed pop rax ; rax = tokens processed
mov [TOKEN_TABLE_ADDR + rax * TOKEN_TABLE_ENTRY_SIZE], cx mov [TOKEN_TABLE_ADDR + rax * 2], cx
inc rax ; plus 1 token processed inc rax ; plus 1 token processed
mov byte [.expecting], E_COMMENT | E_NEWLINE | E_WHITESPACE | E_OPERAND mov byte [.expecting], E_COMMENT | E_NEWLINE | E_WHITESPACE | E_OPERAND
@@ -891,15 +865,15 @@ tokenise:
; cx = token ID ; cx = token ID
.operand_register: .operand_register:
mov [TOKEN_TABLE_ADDR + rax * TOKEN_TABLE_ENTRY_SIZE], cx mov [TOKEN_TABLE_ADDR + rax * 2], cx
inc rax ; another token processed inc rax ; another token processed
jmp .operand_break_continue jmp .operand_break_continue
; cx = token ID ; cx = token ID
.operand_addr_register: .operand_addr_register:
mov word [TOKEN_TABLE_ADDR + rax * TOKEN_TABLE_ENTRY_SIZE], 0x1000 mov word [TOKEN_TABLE_ADDR + rax * 2], 0x1000
inc rax ; 0x1000: addr reg token, next token is the register inc rax ; 0x1000: addr reg token, next token is the register
mov [TOKEN_TABLE_ADDR + rax * TOKEN_TABLE_ENTRY_SIZE], cx mov [TOKEN_TABLE_ADDR + rax * 2], cx
inc rax ; the register as returned by evaluate_operand inc rax ; the register as returned by evaluate_operand
jmp .operand_break_continue jmp .operand_break_continue
@@ -983,11 +957,8 @@ tokenise:
; ------------------------------------------------------------------------------ ; ------------------------------------------------------------------------------
evaluate_operand: evaluate_operand:
push rdi push rdi ; rdi -> start of operand
; rsi = size of operand
push rsi
mov rsi, rdi ; rsi -> start of operand
pop rdi ; rdi = size of operand
call trim_trailing_whitespace call trim_trailing_whitespace
pop rdi ; rdi -> first byte of operand pop rdi ; rdi -> first byte of operand
@@ -1467,38 +1438,38 @@ djb2:
; trims whitespace from the start and end of the given byte array. ; trims whitespace from the start and end of the given byte array.
; ;
; parameters: ; parameters:
; rdi = size of list ; rdi -> start of list
; rsi -> start of list ; rsi = size of list
; ;
; returned: ; returned:
; rax = new size of list ; rax = new size of list
; ------------------------------------------------------------------------------ ; ------------------------------------------------------------------------------
trim_trailing_whitespace: trim_trailing_whitespace:
cmp rdi, 0 ; list of length zero test rsi, rsi ; list of length zero
je .done ; already trimmed jz .done ; already trimmed
push rdi
push rsi push rsi
push rdi
mov dl, [rsi + rdi - 1] ; last element of given list mov dl, [rdi + rsi - 1] ; last element of given list
mov rsi, whitespace_2 ; pointer of whitespace list mov rsi, whitespace_2 ; pointer of whitespace list
mov rdi, 2 ; length of whitespace list mov edi, 2 ; length of whitespace list
call elemb call elemb
pop rsi ; rsi -> start of list pop rdi ; rdi -> start of list
pop rdi ; rdi = size of list pop rsi ; rsi = size of list
cmp al, 0 ; if last element whitespace test eax, eax ; if last element whitespace
je .done ; then break jz .done ; then break
.trim: ; otherwise one shorter .trim: ; otherwise one shorter
dec rdi dec rsi
call trim_trailing_whitespace call trim_trailing_whitespace
ret ret
.done: .done:
mov rax, rdi mov rax, rsi
ret ret
; ------------------------------------------------------------------------------ ; ------------------------------------------------------------------------------
@@ -1510,8 +1481,8 @@ trim_trailing_whitespace:
clear_token_table: clear_token_table:
xor eax, eax ; value to write xor eax, eax ; value to write
mov rcx, TOKEN_TABLE_SIZE / 4 ; number of double words mov ecx, TOKEN_TABLE_SIZE / 4 ; number of double words
mov rdi, TOKEN_TABLE_ADDR ; address to start mov edi, TOKEN_TABLE_ADDR ; address to start
rep stosd rep stosd
ret ret
@@ -1524,8 +1495,8 @@ clear_token_table:
clear_test_arena: clear_test_arena:
xor eax, eax ; value to write xor eax, eax ; value to write
mov rcx, TOKEN_TABLE_SIZE / 4 ; number of double words mov ecx, TOKEN_TABLE_SIZE / 4 ; number of double words
mov rdi, TOKEN_TABLE_ADDR ; address to start mov edi, TOKEN_TABLE_ADDR ; address to start
rep stosd rep stosd
ret ret
@@ -1538,8 +1509,8 @@ clear_test_arena:
clear_output_arena: clear_output_arena:
xor eax, eax ; value to write xor eax, eax ; value to write
mov rcx, OUTPUT_SIZE / 4 ; number of double words mov ecx, OUTPUT_SIZE / 4 ; number of double words
mov rdi, OUTPUT_ADDR ; address to start mov edi, OUTPUT_ADDR ; address to start
rep stosd rep stosd
ret ret

View File

@@ -654,7 +654,7 @@ test_evaluate_operand:
msg_pass: msg_pass:
db 0x0A db 0x0A
times (TEST_LINE_LENGTH + .start + 5 - .end) db " ", ; right align times (TEST_LINE_LENGTH + .start - .end) db " ", ; right align
db 0x1B, "[32m" db 0x1B, "[32m"
.start db "passed." .start db "passed."
.end db 0x1B, "[0m", 0x0A, 0x00 .end db 0x1B, "[0m", 0x0A, 0x00