Это может быть потому что операнд для resb
должен быть critical expression. Это означает, что он должен быть узнаваем на первом проходе ассемблера (a).
Вместо этого вы должны убедиться, что используете только значения, уже известные в первый проход.
Сначала поместите начало этикетки на 0x7c00:
org 0x7c00
start: jmp entry
Затем измените резервирование пространства, чтобы определить другую метку и использовать разницу между ними, чтобы вычислить, сколько байт необходимо:
marker: resb 0x1ffe-(marker-start)
То, что это делает, вычисляет количество уже вычисленных байтов (marker-start
, оба значения, известные до утверждения resb
) и вычитают из числа необходимых вами байтов (0x7dfe - 0x7c00 = 0x01fe
). Тогда он оставляет так много места, как показано на листинг выхода:
0000039 00 DB 0
000003A <res 000001C4> marker: RESB 0x01fe-(marker-start)
* warning: uninitialized space declared in .text section: zeroing
000001FE 55AA DB 0x55, 0xaa
Вы можете увидеть последние два байта по смещению 0x01fe
, которые, учитывая 0x7c00
основания, на самом деле 0x7dfe
по желанию.
(а) Причина, почему ваше выражение считается непознаваемым должен делать, я думаю, с тем, что он использует фактический адрес, который не обязательно известен в проходе 1. Это поддерживается тот факт, что 0xffff - start
также приведет к той же ошибке, несмотря на то, что он использует реальный, уже заявленный ярлык, а не $
.
Вместо использования выражения типа 0xffff - (label1 - label2)
, сами метки могут быть неизвестны, но разница между ними есть.
Хорошо. большое спасибо – user2056639