Weird 8051 assembler code generated by SDCC

I am using SDCC on a 8051 project and the C code uses a switch statement which has some in-line assembler code in several spots. The program compiles without any errors, but the assembler generates a dozen or so "undefined symbol encountered during assembly" errors. The errors all had to do with jump statements, some of which were long jumps and some which were short jumps placed by the peephole optimizer. So I added the '--no-peep' option but the errors persisted.

A snip of the long assembler listing (with the '--no-c-code-in-asm' option) is given below. Note the errors with the 'u' at the beginning of the line. On each of those lines, the assembler claims the label '00111$' is undefined. But you can see that the label '00111$' exists at address 0179h (line 404). I have checked that it is the only symbol with that name in the assembler code. But what is even more odd is that on line 396 (about eight lines above the label) is another jump to that same label, that did not generate an error, and the jump op code is there with a legitimate address for '00111$'.

The '00111$' label isn't the only label that is undefined. As an example, a jump to the '00104$' label at the beginning of the code is fine while a jump to the '00105$' label generates another 'undefined label' error. BTW, these jumps are all associated with CASE labels in the SWITCH statement.

Anybody have an idea what might cause this kind of problem?

00EE 85 E0 95 326 mov _SSDAT, _ACC u 00F1 02 00 00 327 ljmp 00111$ 00F4 328 00104$: 329 ; genInline 00F4 A9*09 330 mov R1, _direction 00F6 B9 01 21 331 cjne R1, #0x01, receive_18 00F9 53 93 F7 332 anl _SSCON, #0b11110111 00FC 85*02 95 333 mov _SSDAT, _adr_h 00FF 334 check_fir: 00FF 85 93 E0 335 mov _ACC, _SSCON 0102 30 E3 FA 336 jnb _ACC_3, check_fir 0105 53 93 F7 337 anl _SSCON, #0b11110111 0108 85*03 95 338 mov _SSDAT, _adr_l 010B 339 check_sec: 010B 85 93 E0 340 mov _ACC, _SSCON 010E 30 E3 FA 341 jnb _ACC_3, check_sec 0111 53 93 F7 342 anl _SSCON, #0b11110111 0114 85*00 95 343 mov _SSDAT, _TWI_data 0117 02s01r29 344 ljmp c18b 011A 345 receive_18: 011A 85*02 95 346 mov _SSDAT, _adr_h 011D 53 93 F7 347 anl _SSCON, #0b11110111 0120 348 c18a: 0120 85 93 E0 349 mov _ACC, _SSCON 0123 30 E3 FA 350 jnb _ACC_3, c18a 0126 85*03 95 351 mov _SSDAT, _adr_l 0129 352 c18b: 0129 00 353 nop u 012A 02 00 00 354 ljmp 00111$ 012D 355 00105$: 356 ; genOr 012D 43 93 10 357 orl _SSCON,#0x10 358 ; genAssign 0130 C2*00 359 clr _TWI_busy u 0132 02 00 00 360 ljmp 00111$ 0135 361 00106$: 362 ; genInline 0135 A9*09 363 mov R1, _direction 0137 B9 01 0B 364 cjne R1, #0x01, receive_28 013A 43 93 10 365 orl _SSCON, #0x10 013D 85 93*05 366 mov _stop_ind, _SSCON 0140 C2*00 367 clr _TWI_busy 0142 02s01r48 368 ljmp c28a 0145 369 receive_28: 0145 43 93 20 370 orl _SSCON, #0x20 0148 371 c28a: 0148 00 372 nop u 0149 02 00 00 373 ljmp 00111$ 014C 374 00107$: 375 ; genOr 014C 43 93 10 376 orl _SSCON,#0x10 377 ; genAssign 014F C2*00 378 clr _TWI_busy u 0151 02 00 00 379 ljmp 00111$ 0154 380 00108$: 381 ; genOr 0154 43 93 10 382 orl _SSCON,#0x10 383 ; genAssign 0157 C2*00 384 clr _TWI_busy u 0159 02 00 00 385 ljmp 00111$ 015C 386 00109$: 387 ; genInline 015C 53 93 F7 388 anl _SSCON, #0b11110111 015F 389 c40a: 015F 85 93 E0 390 mov _ACC, _SSCON 0162 30 E3 FA 391 jnb _ACC_3, c40a 0165 85 95*04 392 mov _TWI_data_i, _SSDAT 0168 53 93 FB 393 anl _SSCON, #0b11111011 394 ; genAnd 016B 53 93 F7 395 anl _SSCON,#0xF7 016E 02s01r79 396 ljmp 00111$ 0171 397 00110$: 398 ; genOr 0171 43 93 10 399 orl _SSCON,#0x10 400 ; genAssign 0174 85 93*05 401 mov _stop_ind,_SSCON 402 ; genAssign 0177 C2*00 403 clr _TWI_busy 0179 404 00111$: 405 ; genAnd 0179 53 93 F7 406 anl _SSCON,#0xF7 017C 407 00112$: 017C D0 D0 408 pop psw 017E D0 02 409 pop ar2
Reply to
Desert Rat
Loading thread data ...

An update: I replaced the SWITCH statement with a series of IF statements and recompiled the program. It still compiles without error, but now generates only three "undefined symbol" errors. There were ten CASE clauses in the SWITCH statement, converted now to ten IF statements. Most of the ten IF statements run a chunk of code that have in-line assembler. But only three have in-line assembler that have labels and assembler jumps. Those three are the ones generating the errors. Does this mean in-line assembler in SDCC cannot have labels and can never branch? Sounds a little unreasonable.

Reply to
Desert Rat

I am not familiar with that assembler and compiler, so this is just a guess: Some assemblers support labels with a limited scope, to make easier to generate temporary labels. (for destination of 'if' statement branches, etc.) You can have several identical labels with no conflict, since each one will be valid only between a limited range of lines in the file. These labels have a special syntax, an the "00???$" format suggests this. Their range is usually terminated by "normal" labels. So this is the guess: something in your in-line assembly (labels probably) is terminating the range of the compiler generated limited-scope labels, so the jump statements so no see them. Try removing them temporarily to see if that is the case.

Reply to
Roberto Waltman

Or better: Try editing the assembly file, replacing the compiler generated labels with conventional ones:

00111$ --> label00111, etc.
Reply to
Roberto Waltman

Roberto,

You are exactly right about the issue. See the new thread I started called "Bug with SDCC and in-line assembler labels?"

Reply to
Desert Rat

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.