diff --git a/linux/labels_baremetal b/linux/labels_baremetal index ce80777e..c1db3ad6 100755 Binary files a/linux/labels_baremetal and b/linux/labels_baremetal differ diff --git a/linux/labels_baremetal.subx b/linux/labels_baremetal.subx index 54d45425..be1dc768 100644 --- a/linux/labels_baremetal.subx +++ b/linux/labels_baremetal.subx @@ -435,6 +435,10 @@ emit-output: # in: (addr stream byte), out: (addr buffered-file), labels: (addr # emit(out, *address, 4) # else if has-metadata?(word-slice, "disp8") # value = *address - address-of-next-instruction + # if value > 127 + # abort + # if value < -128 + # abort # emit(out, value, 1) # else if has-metadata?(word-slice, "disp32") # if far-jump-or-call? @@ -1013,6 +1017,12 @@ $emit-output:emit-disp8: # var value/eax: int = *address - address-of-next-instruction 8b/copy 0/mod/indirect 6/rm32/esi . . . 0/r32/eax . . # copy *esi to eax 29/subtract 3/mod/direct 0/rm32/eax . . . 3/r32/ebx . . # subtract ebx from eax + # if (value > 127) abort + 3d/compare-eax-and 0x7f/imm32 + 0f 8f/jump-if-> $emit-output:error-disp8-too-large/disp32 + # if (value < -128) abort + 3d/compare-eax-and -0x80/imm32 + 0f 8c/jump-if-< $emit-output:error-disp8-too-large/disp32 # emit-hex(out, value, 1) # . . push args 68/push 1/imm32 @@ -1139,6 +1149,66 @@ $emit-output:abort: e8/call syscall_exit/disp32 # never gets here +$emit-output:error-disp8-too-large: + # print(stderr, word-slice ": label too far below for /disp8; use /disp32") + # . write-slice-buffered(Stderr, word-slice) + # . . push args + 52/push-edx + 68/push Stderr/imm32 + # . . call + e8/call write-slice-buffered/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # . flush(Stderr) + # . . push args + 68/push Stderr/imm32 + # . . call + e8/call flush/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + # . _write(2/stderr, msg) + # . . push args + 68/push ": label too far below for /disp8; use /disp32"/imm32 + 68/push 2/imm32/stderr + # . . call + e8/call _write/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # . syscall_exit(1) + bb/copy-to-ebx 1/imm32 + e8/call syscall_exit/disp32 + # never gets here + +$emit-output:error-disp8-too-small: + # print(stderr, word-slice ": label too far above for /disp8; use /disp32") + # . write-slice-buffered(Stderr, word-slice) + # . . push args + 52/push-edx + 68/push Stderr/imm32 + # . . call + e8/call write-slice-buffered/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # . flush(Stderr) + # . . push args + 68/push Stderr/imm32 + # . . call + e8/call flush/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + # . _write(2/stderr, msg) + # . . push args + 68/push ": label too far above for /disp8; use /disp32"/imm32 + 68/push 2/imm32/stderr + # . . call + e8/call _write/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # . syscall_exit(1) + bb/copy-to-ebx 1/imm32 + e8/call syscall_exit/disp32 + # never gets here + test-emit-output-non-far-control-flow: # labels turn into absolute addresses if opcodes are not far jumps or calls #