Handle additional jumps for listing 50

This commit is contained in:
Joseph Ferano 2025-03-21 17:19:48 +07:00
parent 99fd7fabd7
commit 0e90e2c23c
5 changed files with 94 additions and 10 deletions

38
asm_files/list-0050.asm Normal file
View File

@ -0,0 +1,38 @@
; ========================================================================
;
; (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved.
;
; This software is provided 'as-is', without any express or implied
; warranty. In no event will the authors be held liable for any damages
; arising from the use of this software.
;
; Please see https://computerenhance.com for further information
;
; ========================================================================
; ========================================================================
; LISTING 50
; ========================================================================
bits 16
mov ax, 10
mov bx, 10
mov cx, 10
label_0:
cmp bx, cx
je label_1
add ax, 1
jp label_2
label_1:
sub bx, 5
jb label_3
label_2:
sub cx, 2
label_3:
loopnz label_0

37
asm_files/list-0050.txt Normal file
View File

@ -0,0 +1,37 @@
--- test\listing_0050_challenge_jumps execution ---
mov ax, 10 ; ax:0x0->0xa ip:0x0->0x3
mov bx, 10 ; bx:0x0->0xa ip:0x3->0x6
mov cx, 10 ; cx:0x0->0xa ip:0x6->0x9
cmp bx, cx ; ip:0x9->0xb flags:->PZ
je $+7 ; ip:0xb->0x12
sub bx, 5 ; bx:0xa->0x5 ip:0x12->0x15 flags:PZ->P
jb $+5 ; ip:0x15->0x17
sub cx, 2 ; cx:0xa->0x8 ip:0x17->0x1a flags:P->
loopnz $-17 ; cx:0x8->0x7 ip:0x1a->0x9
cmp bx, cx ; ip:0x9->0xb flags:->CAS
je $+7 ; ip:0xb->0xd
add ax, 1 ; ax:0xa->0xb ip:0xd->0x10 flags:CAS->
jp $+7 ; ip:0x10->0x12
sub bx, 5 ; bx:0x5->0x0 ip:0x12->0x15 flags:->PZ
jb $+5 ; ip:0x15->0x17
sub cx, 2 ; cx:0x7->0x5 ip:0x17->0x1a flags:PZ->P
loopnz $-17 ; cx:0x5->0x4 ip:0x1a->0x9
cmp bx, cx ; ip:0x9->0xb flags:P->CPAS
je $+7 ; ip:0xb->0xd
add ax, 1 ; ax:0xb->0xc ip:0xd->0x10 flags:CPAS->P
jp $+7 ; ip:0x10->0x17
sub cx, 2 ; cx:0x4->0x2 ip:0x17->0x1a flags:P->
loopnz $-17 ; cx:0x2->0x1 ip:0x1a->0x9
cmp bx, cx ; ip:0x9->0xb flags:->CPAS
je $+7 ; ip:0xb->0xd
add ax, 1 ; ax:0xc->0xd ip:0xd->0x10 flags:CPAS->
jp $+7 ; ip:0x10->0x12
sub bx, 5 ; bx:0x0->0xfffb ip:0x12->0x15 flags:->CAS
jb $+5 ; ip:0x15->0x1a
loopnz $-17 ; cx:0x1->0x0 ip:0x1a->0x1c
Final registers:
ax: 0x000d (13)
bx: 0xfffb (65531)
ip: 0x001c (28)
flags: CAS

View File

@ -108,25 +108,33 @@ execute_instruction :: proc(cpu: ^Cpu, inst: Instruction) {
check_carry_flag(cpu, dst_val, src_val, false) check_carry_flag(cpu, dst_val, src_val, false)
} }
} else if jmp_offset,ok := inst.src.(Jump); ok { } else if jmp_offset,ok := inst.src.(Jump); ok {
jump: bool
#partial switch inst.opname { #partial switch inst.opname {
case .JNZ, .JNE: case .JNZ, .JNE: jump = !cpu.flags[.ZF]
if !cpu.flags[.ZF] { case .JE, .JZ: jump = cpu.flags[.ZF]
case .JP, .JPE: jump = cpu.flags[.PF]
case .JB, .JNAE: jump = cpu.flags[.CF]
case .LOOPNZ, .LOOPNE:
cpu.registers[.cx].full -= 1
// According to this resource, the loopnz inst does not change any flags
// https://yassinebridi.github.io/asm-docs/8086_instruction_set.html#LOOPNZ
// check_zero_flag(cpu, cpu.registers[.cx].full)
jump = cpu.registers[.cx].full != 0 && !cpu.flags[.ZF]
}
if jump {
cpu.registers[.ip].full += i16(jmp_offset) cpu.registers[.ip].full += i16(jmp_offset)
if jmp_offset < 0 {
cpu.registers[.ip].full -= i16(inst.bytes_read) cpu.registers[.ip].full -= i16(inst.bytes_read)
} }
} }
}
}
} }
execute_instructions :: proc(cpu: ^Cpu, instructions: DecodedInstructions) { execute_instructions :: proc(cpu: ^Cpu, instructions: DecodedInstructions) {
halt := false halt := false
fmt.println(instructions.total_bytes_decoded)
for !halt && get_ip(cpu) < instructions.total_bytes_decoded { for !halt && get_ip(cpu) < instructions.total_bytes_decoded {
inst,ok := instructions.inst_map[get_ip(cpu)] inst,ok := instructions.inst_map[get_ip(cpu)]
if !ok { if !ok {
// Something went wrong with a jump, most likely panic("Something went wrong with a jump, most likely")
} }
cpu.registers[.ip].full += i16(inst.bytes_read) cpu.registers[.ip].full += i16(inst.bytes_read)
execute_instruction(cpu, inst) execute_instruction(cpu, inst)

View File

@ -106,6 +106,7 @@ Op :: enum {
LOOP, LOOP,
LOOPZ, LOOPZ,
LOOPNZ, LOOPNZ,
LOOPNE,
JCXZ, JCXZ,
} }

View File

@ -44,7 +44,7 @@ main :: proc() {
} }
cpu := Cpu { cpu := Cpu {
memory = make([dynamic]u8, 65536), memory = make([dynamic]u8, 1_048_576), // Exact num per the manual
} }
execute_instructions(&cpu, decoded_insts) execute_instructions(&cpu, decoded_insts)